From fb907c4e9e9e24c10daf0f191121c1514e4623bf Mon Sep 17 00:00:00 2001 From: Max Korsunov Date: Wed, 27 Mar 2024 22:01:42 +0100 Subject: [PATCH] feat: JSON schema for Tact configuration files (#194) --- .github/workflows/tact.yml | 4 +++ CHANGELOG.md | 1 + grammar/configSchema.json | 60 ++++++++++++++++++++++++++++++++++ package.json | 4 ++- src/config/parseConfig.ts | 3 +- src/test/test-tact.config.json | 21 ++++++------ tact.config.json | 3 +- yarn.lock | 58 ++++++++++++++++++++++++++++++-- 8 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 grammar/configSchema.json diff --git a/.github/workflows/tact.yml b/.github/workflows/tact.yml index 916e1d61d..0a8b247c1 100644 --- a/.github/workflows/tact.yml +++ b/.github/workflows/tact.yml @@ -41,6 +41,10 @@ jobs: run: | yarn lint + - name: Check that tact.config.json adheres to the JSON schema + run: | + yarn lint:schema + - name: Compare Tact version from CLI flag `--version` against package.json if: runner.os != 'Windows' run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index da8ef070a..8349fee5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `log2` and `log` math functions in `@stdlib/math`: PR [#166](https://github.com/tact-lang/tact/pull/166) - Reserve mode constants in `@stdlib/reserve`, namely `ReserveExact`, `ReserveAllExcept`, `ReserveAtMost`, `ReserveAddOriginalBalance`, `ReserveInvertSign`, `ReserveBounceIfActionFail`: PR [#173](https://github.com/tact-lang/tact/pull/173) +- JSON Schema for `tact.config.json`: PR [#194](https://github.com/tact-lang/tact/pull/194) ### Changed - Update the `dump` function to handle addresses: PR [#175](https://github.com/tact-lang/tact/pull/175) diff --git a/grammar/configSchema.json b/grammar/configSchema.json new file mode 100644 index 000000000..5b6f35226 --- /dev/null +++ b/grammar/configSchema.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://json-schema.org/schema#", + "$id": "http://raw.githubusercontent.com/tact-lang/tact/main/grammar/configSchema.json", + "title": "Tact configuration schema", + "description": "JSON Schema for tact.config.json", + "type": "object", + "required": ["projects"], + "properties": { + "projects": { + "type": "array", + "description": "List of Tact projects with respective compilation options. Each .tact file represents its own Tact project.", + "items": { + "type": "object", + "required": ["name", "path", "output"], + "properties": { + "name": { + "type": "string", + "description": "Name of the project. All generated files are prefixed with it." + }, + "path": { + "type": "string", + "description": "Path to the project's Tact file. You can only specify one Tact file per project." + }, + "output": { + "type": "string", + "description": "Path to the directory where all generated files will be placed." + }, + "options": { + "type": "object", + "description": "Compilation options for the project.", + "properties": { + "debug": { + "type": "boolean", + "description": "False by default. If set to true, enables debug output of a contract and allows usage of `dump()` function, which is useful for debugging purposes. With this option enabled, the contract will report that it was compiled in debug mode using the supported_interfaces method.\n\nRead more on debugging Tact code: https://docs.tact-lang.org/book/debug." + }, + "masterchain": { + "type": "boolean", + "description": "False by default. If set to true, enables masterchain support.\n\nRead more about masterchain: https://docs.tact-lang.org/book/masterchain." + }, + "external": { + "type": "boolean", + "description": "False by default. If set to true, enables support of external message receivers.\n\nRead more about external message receivers: https://docs.tact-lang.org/book/external." + }, + "experimental": { + "type": "object", + "description": "Experimental options that might be removed in the future. Use with caution!", + "properties": { + "inline": { + "type": "boolean", + "description": "False by default. If set to true, enables inlining of all functions in contracts. This can reduce gas usage at the cost of bigger contracts." + } + } + } + } + } + } + } + } + } +} diff --git a/package.json b/package.json index 0418f66c1..84bbd51a7 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "test": "jest", "coverage": "cross-env COVERAGE=true jest", "release": "yarn clean && yarn build && yarn coverage && yarn release-it --npm.yarn1", - "lint": "yarn eslint ." + "lint": "yarn eslint .", + "lint:schema": "ajv validate -s grammar/configSchema.json -d tact.config.json" }, "files": [ "dist/**/*", @@ -59,6 +60,7 @@ "@types/qs": "^6.9.7", "@typescript-eslint/eslint-plugin": "^7.0.2", "@typescript-eslint/parser": "^7.0.2", + "ajv-cli": "^5.0.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", "glob": "^8.1.0", diff --git a/src/config/parseConfig.ts b/src/config/parseConfig.ts index f0ae1f7e0..31ea905b9 100644 --- a/src/config/parseConfig.ts +++ b/src/config/parseConfig.ts @@ -17,6 +17,7 @@ const projectSchema = z.object({ }).strict(); const configSchema = z.object({ + $schema: z.string().optional(), projects: z.array(projectSchema) }).strict(); @@ -31,4 +32,4 @@ export function parseConfig(src: string) { export function verifyConfig(config: Config) { return configSchema.parse(config); -} \ No newline at end of file +} diff --git a/src/test/test-tact.config.json b/src/test/test-tact.config.json index cbabf7f06..f275e1c3d 100644 --- a/src/test/test-tact.config.json +++ b/src/test/test-tact.config.json @@ -1,12 +1,13 @@ { - "projects": [ - { - "name": "implicit-init-2", - "path": "./features/implicit-init-2.tact", - "output": "./features/output", - "options": { - "debug": true - } + "$schema": "http://raw.githubusercontent.com/tact-lang/tact/main/grammar/configSchema.json", + "projects": [ + { + "name": "implicit-init-2", + "path": "./features/implicit-init-2.tact", + "output": "./features/output", + "options": { + "debug": true } - ] - } \ No newline at end of file + } + ] +} diff --git a/tact.config.json b/tact.config.json index 36238f424..d1d49aca2 100644 --- a/tact.config.json +++ b/tact.config.json @@ -1,4 +1,5 @@ { + "$schema": "http://raw.githubusercontent.com/tact-lang/tact/main/grammar/configSchema.json", "projects": [ { "name": "echo", @@ -269,4 +270,4 @@ } } ] -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 8733907a6..c423b79f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1313,6 +1313,19 @@ agent-base@^7.0.2, agent-base@^7.1.0: dependencies: debug "^4.3.4" +ajv-cli@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ajv-cli/-/ajv-cli-5.0.0.tgz#78956ed2934e6dde4c9e696b587be1c2998862e8" + integrity sha512-LY4m6dUv44HTyhV+u2z5uX4EhPYTM38Iv1jdgDJJJCyOOuqB8KtZEGjPZ2T+sh5ZIJrXUfgErYx/j3gLd3+PlQ== + dependencies: + ajv "^8.0.0" + fast-json-patch "^2.0.0" + glob "^7.1.0" + js-yaml "^3.14.0" + json-schema-migrate "^2.0.0" + json5 "^2.1.3" + minimist "^1.2.0" + ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -1323,6 +1336,16 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + ansi-align@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" @@ -2455,6 +2478,11 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -2482,6 +2510,13 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-json-patch@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.2.1.tgz#18150d36c9ab65c7209e7d4eb113f4f8eaabe6d9" + integrity sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -2693,7 +2728,7 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@^7.0.0, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.0, glob@^7.1.0, glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -4099,7 +4134,7 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1: +js-yaml@^3.13.1, js-yaml@^3.14.0: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -4134,17 +4169,29 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-schema-migrate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/json-schema-migrate/-/json-schema-migrate-2.0.0.tgz#335ef5218cd32fcc96c1ddce66c71ba586224496" + integrity sha512-r38SVTtojDRp4eD6WsCqiE0eNDt4v1WalBXb9cyZYw9ai5cGtBwzRNWjHzJl38w6TxFkXAIA7h+fyX3tnrAFhQ== + dependencies: + ajv "^8.0.0" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@^2.2.3: +json5@^2.1.3, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -5095,6 +5142,11 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + resolve-alpn@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"