Explorar el Código

refactor: Improve script reuse (#31)

* [wip]: scripts refactoring

* [wip]: use TypeScript in scripts

* [wip]: add and use CrateEnvironment

* [wip]: add getDefaultCrateEnvironment

* Moved to helpers

* Remove unused

* Complete CrateEnvironment type

* Update scripts path

* Add rust test script

* Update crate type

* Fix workflow scripts

* Use tsx

* Add missing toolchain

* Typo

* Add missing crate type

* Simplify scripts

* Fix imports

* Remove unused

* Fix crate name

---------

Co-authored-by: Loris Leiva <loris.leiva@gmail.com>
Fernando Otero hace 11 meses
padre
commit
f1c7cc15ca
Se han modificado 39 ficheros con 540 adiciones y 358 borrados
  1. 1 1
      .github/actions/setup/action.yml
  2. 16 15
      .github/workflows/main.yml
  3. 7 7
      .github/workflows/publish-js-client.yml
  4. 7 7
      .github/workflows/publish-rust-client.yml
  5. 26 18
      package.json
  6. 283 0
      pnpm-lock.yaml
  7. 1 1
      scripts/ci/set-env.mts
  8. 0 30
      scripts/client/format-rust.mjs
  9. 0 24
      scripts/client/lint-rust-clippy.mjs
  10. 0 18
      scripts/client/lint-rust-docs.mjs
  11. 0 19
      scripts/client/lint-rust-features.mjs
  12. 0 17
      scripts/client/lint-rust.mjs
  13. 0 18
      scripts/client/test-rust.mjs
  14. 1 1
      scripts/helpers/check-solana-version.mts
  15. 10 6
      scripts/helpers/generate-clients.mts
  16. 1 1
      scripts/helpers/link-solana-version.mts
  17. 7 6
      scripts/helpers/start-validator.mts
  18. 0 0
      scripts/helpers/stop-validator.mts
  19. 3 3
      scripts/helpers/upgrade-template.mts
  20. 41 21
      scripts/helpers/utils.mts
  21. 0 25
      scripts/interface/format.mjs
  22. 0 35
      scripts/interface/lint-clippy.mjs
  23. 0 13
      scripts/interface/lint-docs.mjs
  24. 0 14
      scripts/interface/lint-features.mjs
  25. 0 17
      scripts/interface/lint.mjs
  26. 0 16
      scripts/interface/test.mjs
  27. 0 14
      scripts/interface/wasm.mjs
  28. 1 1
      scripts/js/format.mts
  29. 1 1
      scripts/js/lint.mts
  30. 1 1
      scripts/js/publish.mts
  31. 1 1
      scripts/js/test.mts
  32. 20 0
      scripts/rust/format.mts
  33. 22 0
      scripts/rust/lint-clippy.mts
  34. 12 0
      scripts/rust/lint-docs.mts
  35. 13 0
      scripts/rust/lint-features.mts
  36. 17 0
      scripts/rust/lint.mts
  37. 12 7
      scripts/rust/publish.mts
  38. 25 0
      scripts/rust/test.mts
  39. 11 0
      scripts/rust/wasm.mts

+ 1 - 1
.github/actions/setup/action.yml

@@ -35,7 +35,7 @@ runs:
 
     - name: Set Environment Variables
       shell: bash
-      run: pnpm zx ./scripts/ci/set-env.mjs
+      run: pnpm tsx ./scripts/ci/set-env.mts
 
     - name: Install Rust 'build' Toolchain
       if: ${{ contains(inputs.toolchain, 'build') }}

+ 16 - 15
.github/workflows/main.yml

@@ -17,10 +17,10 @@ jobs:
         uses: ./.github/actions/setup
 
       - name: Format Client JS
-        run: pnpm clients:js:format
+        run: pnpm js:format
 
       - name: Lint Client JS
-        run: pnpm clients:js:lint
+        run: pnpm js:lint
 
   format_and_lint_client_rust:
     name: Format & Lint Client Rust
@@ -35,16 +35,16 @@ jobs:
           toolchain: format, lint
 
       - name: Format
-        run: pnpm clients:rust:format
+        run: pnpm rust:format
 
       - name: Lint / Clippy
-        run: pnpm zx ./scripts/client/lint-rust-clippy.mjs
-
-      - name: Lint / Features
-        run: pnpm zx ./scripts/client/lint-rust-features.mjs
+        run: pnpm rust:lint:clippy
 
       - name: Lint / Docs
-        run: pnpm zx ./scripts/client/lint-rust-docs.mjs
+        run: pnpm rust:lint:docs
+
+      - name: Lint / Features
+        run: pnpm rust:lint:features
 
   format_and_lint_interface:
     name: Format & Lint Interface
@@ -62,13 +62,13 @@ jobs:
         run: pnpm interface:format
 
       - name: Lint / Clippy
-        run: pnpm zx ./scripts/interface/lint-clippy.mjs
-
-      - name: Lint / Features
-        run: pnpm zx ./scripts/interface/lint-features.mjs
+        run: pnpm interface:lint:clippy
 
       - name: Lint / Docs
-        run: pnpm zx ./scripts/interface/lint-docs.mjs
+        run: pnpm interface:lint:docs
+
+      - name: Lint / Features
+        run: pnpm interface:lint:features
 
   wasm_interface:
     name: Build Interface in WASM
@@ -144,7 +144,7 @@ jobs:
           solana: true
 
       - name: Test Client JS
-        run: pnpm clients:js:test
+        run: pnpm js:test
 
   test_client_rust:
     name: Test Client Rust
@@ -158,7 +158,8 @@ jobs:
         uses: ./.github/actions/setup
         with:
           cargo-cache-key: cargo-rust-client
+          toolchain: test
           solana: true
 
       - name: Test Client Rust
-        run: pnpm clients:rust:test
+        run: pnpm rust:test

+ 7 - 7
.github/workflows/publish-js-client.yml

@@ -40,14 +40,14 @@ jobs:
         with:
           solana: true
 
-      - name: Format JS Client
-        run: pnpm clients:js:format
+      - name: Format
+        run: pnpm js:format
 
-      - name: Lint JS Client
-        run: pnpm clients:js:lint
+      - name: Lint
+        run: pnpm js:lint
 
-      - name: Test JS Client
-        run: pnpm clients:js:test
+      - name: Test
+        run: pnpm js:test
 
   publish_js:
     name: Publish JS client
@@ -83,7 +83,7 @@ jobs:
 
       - name: Publish JS Client
         id: publish
-        run: pnpm clients:js:publish ${{ inputs.level }} ${{ inputs.tag }}
+        run: pnpm js:publish ${{ inputs.level }} ${{ inputs.tag }}
 
       - name: Push Commit and Tag
         run: git push origin --follow-tags

+ 7 - 7
.github/workflows/publish-rust-client.yml

@@ -48,14 +48,14 @@ jobs:
           rustfmt: true
           solana: true
 
-      - name: Format Rust Client
-        run: pnpm clients:rust:format
+      - name: Format
+        run: pnpm rust:format
 
-      - name: Lint Rust Client
-        run: pnpm clients:rust:lint
+      - name: Lint
+        run: pnpm rust:lint
 
-      - name: Test Rust Client
-        run: pnpm clients:rust:test
+      - name: Test
+        run: pnpm rust:test
 
   publish_rust:
     name: Publish Rust Client
@@ -109,7 +109,7 @@ jobs:
             OPTIONS=""
           fi
 
-          pnpm clients:rust:publish $LEVEL $OPTIONS
+          pnpm rust:publish $LEVEL $OPTIONS
 
       - name: Push Commit and Tag
         if: github.event.inputs.dry_run != 'true'

+ 26 - 18
package.json

@@ -1,32 +1,40 @@
 {
   "private": true,
   "scripts": {
-    "solana:check": "zx ./scripts/check-solana-version.mjs",
-    "solana:link": "zx ./scripts/link-solana-version.mjs",
+    "solana:check": "tsx ./scripts/helpers/check-solana-version.mts",
+    "solana:link": "tsx ./scripts/helpers/link-solana-version.mts",
     "generate": "pnpm generate:clients",
-    "generate:clients": "zx ./scripts/generate-clients.mjs",
-    "validator:start": "zx ./scripts/start-validator.mjs",
+    "generate:clients": "tsx ./scripts/helpers/generate-clients.mts",
+    "validator:start": "tsx ./scripts/helpers/start-validator.mts",
     "validator:restart": "pnpm validator:start --restart",
-    "validator:stop": "zx ./scripts/stop-validator.mjs",
-    "clients:js:format": "zx ./scripts/client/format-js.mjs",
-    "clients:js:lint": "zx ./scripts/client/lint-js.mjs",
-    "clients:js:publish": "zx ./scripts/client/publish-js.mjs",
-    "clients:js:test": "zx ./scripts/client/test-js.mjs",
-    "clients:rust:format": "zx ./scripts/client/format-rust.mjs",
-    "clients:rust:lint": "zx ./scripts/client/lint-rust.mjs",
-    "clients:rust:publish": "zx ./scripts/client/publish-rust.mjs",
-    "clients:rust:test": "zx ./scripts/client/test-rust.mjs",
-    "interface:format": "zx ./scripts/interface/format.mjs",
-    "interface:lint": "zx ./scripts/interface/lint.mjs",
-    "interface:test": "zx ./scripts/interface/test.mjs",
-    "interface:wasm": "zx ./scripts/interface/wasm.mjs",
-    "template:upgrade": "zx ./scripts/upgrade-template.mjs"
+    "validator:stop": "tsx ./scripts/helpers/stop-validator.mts",
+    "js:format": "tsx ./scripts/js/format.mts",
+    "js:lint": "tsx ./scripts/js/lint.mts",
+    "js:publish": "tsx ./scripts/js/publish.mts",
+    "js:test": "tsx ./scripts/js/test.mts",
+    "rust:format": "tsx ./scripts/rust/format.mts clients/rust",
+    "rust:lint": "tsx ./scripts/rust/lint.mts clients/rust",
+    "rust:lint:clippy": "tsx ./scripts/rust/lint-clippy.mts clients/rust",
+    "rust:lint:docs": "tsx ./scripts/rust/lint-docs.mts clients/rust",
+    "rust:lint:features": "tsx ./scripts/rust/lint-features.mts clients/rust",
+    "rust:publish": "tsx ./scripts/rust/publish.mts clients/rust",
+    "rust:test": "tsx ./scripts/rust/test.mts clients/rust",
+    "interface:format": "tsx ./scripts/rust/format.mts interface",
+    "interface:lint": "tsx ./scripts/rust/lint.mts interface",
+    "interface:lint:clippy": "tsx ./scripts/rust/lint-clippy.mts interface",
+    "interface:lint:docs": "tsx ./scripts/rust/lint-docs.mts interface",
+    "interface:lint:features": "tsx ./scripts/rust/lint-features.mts interface",
+    "interface:publish": "tsx ./scripts/rust/publish.mts interface",
+    "interface:test": "tsx ./scripts/rust/test.mts interface",
+    "interface:wasm": "tsx ./scripts/rust/wasm.mts interface",
+    "template:upgrade": "tsx ./scripts/helpers/upgrade-template.ts"
   },
   "devDependencies": {
     "@codama/renderers-js": "^1.1.0",
     "@codama/renderers-rust": "^1.0.4",
     "@iarna/toml": "^2.2.5",
     "codama": "^1.1.0",
+    "tsx": "^4.19.2",
     "typescript": "^5.5.2",
     "zx": "^7.2.3"
   },

+ 283 - 0
pnpm-lock.yaml

@@ -20,6 +20,9 @@ importers:
       codama:
         specifier: ^1.1.0
         version: 1.1.0
+      tsx:
+        specifier: ^4.19.2
+        version: 4.19.2
       typescript:
         specifier: ^5.5.2
         version: 5.5.3
@@ -60,6 +63,150 @@ packages:
   '@codama/visitors@1.1.0':
     resolution: {integrity: sha512-QpAShuxemS8oplHDXNqnUnYwhJq58RZjfZ/KMIpdm88OCBnQRO4YfM/zQLEvXjA+tpwJpe4WnL6opTLLnSYThw==}
 
+  '@esbuild/aix-ppc64@0.23.1':
+    resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
+    engines: {node: '>=18'}
+    cpu: [ppc64]
+    os: [aix]
+
+  '@esbuild/android-arm64@0.23.1':
+    resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [android]
+
+  '@esbuild/android-arm@0.23.1':
+    resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
+    engines: {node: '>=18'}
+    cpu: [arm]
+    os: [android]
+
+  '@esbuild/android-x64@0.23.1':
+    resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [android]
+
+  '@esbuild/darwin-arm64@0.23.1':
+    resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [darwin]
+
+  '@esbuild/darwin-x64@0.23.1':
+    resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [darwin]
+
+  '@esbuild/freebsd-arm64@0.23.1':
+    resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [freebsd]
+
+  '@esbuild/freebsd-x64@0.23.1':
+    resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [freebsd]
+
+  '@esbuild/linux-arm64@0.23.1':
+    resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [linux]
+
+  '@esbuild/linux-arm@0.23.1':
+    resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
+    engines: {node: '>=18'}
+    cpu: [arm]
+    os: [linux]
+
+  '@esbuild/linux-ia32@0.23.1':
+    resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
+    engines: {node: '>=18'}
+    cpu: [ia32]
+    os: [linux]
+
+  '@esbuild/linux-loong64@0.23.1':
+    resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
+    engines: {node: '>=18'}
+    cpu: [loong64]
+    os: [linux]
+
+  '@esbuild/linux-mips64el@0.23.1':
+    resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
+    engines: {node: '>=18'}
+    cpu: [mips64el]
+    os: [linux]
+
+  '@esbuild/linux-ppc64@0.23.1':
+    resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
+    engines: {node: '>=18'}
+    cpu: [ppc64]
+    os: [linux]
+
+  '@esbuild/linux-riscv64@0.23.1':
+    resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
+    engines: {node: '>=18'}
+    cpu: [riscv64]
+    os: [linux]
+
+  '@esbuild/linux-s390x@0.23.1':
+    resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
+    engines: {node: '>=18'}
+    cpu: [s390x]
+    os: [linux]
+
+  '@esbuild/linux-x64@0.23.1':
+    resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [linux]
+
+  '@esbuild/netbsd-x64@0.23.1':
+    resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [netbsd]
+
+  '@esbuild/openbsd-arm64@0.23.1':
+    resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [openbsd]
+
+  '@esbuild/openbsd-x64@0.23.1':
+    resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [openbsd]
+
+  '@esbuild/sunos-x64@0.23.1':
+    resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [sunos]
+
+  '@esbuild/win32-arm64@0.23.1':
+    resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [win32]
+
+  '@esbuild/win32-ia32@0.23.1':
+    resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
+    engines: {node: '>=18'}
+    cpu: [ia32]
+    os: [win32]
+
+  '@esbuild/win32-x64@0.23.1':
+    resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [win32]
+
   '@iarna/toml@2.2.5':
     resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
 
@@ -175,6 +322,11 @@ packages:
     resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
     engines: {node: '>= 0.4'}
 
+  esbuild@0.23.1:
+    resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
+    engines: {node: '>=18'}
+    hasBin: true
+
   event-stream@3.3.4:
     resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==}
 
@@ -207,6 +359,11 @@ packages:
     resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
     engines: {node: '>=14.14'}
 
+  fsevents@2.3.3:
+    resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+
   function-bind@1.1.2:
     resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
 
@@ -218,6 +375,9 @@ packages:
     resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
     engines: {node: '>= 0.4'}
 
+  get-tsconfig@4.8.1:
+    resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
+
   glob-parent@5.1.2:
     resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
     engines: {node: '>= 6'}
@@ -339,6 +499,9 @@ packages:
   queue-microtask@1.2.3:
     resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
 
+  resolve-pkg-maps@1.0.0:
+    resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
   reusify@1.0.4:
     resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
     engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
@@ -367,6 +530,11 @@ packages:
     resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
     engines: {node: '>=8.0'}
 
+  tsx@4.19.2:
+    resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==}
+    engines: {node: '>=18.0.0'}
+    hasBin: true
+
   typescript@5.5.3:
     resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==}
     engines: {node: '>=14.17'}
@@ -476,6 +644,78 @@ snapshots:
       '@codama/nodes': 1.1.0
       '@codama/visitors-core': 1.1.0
 
+  '@esbuild/aix-ppc64@0.23.1':
+    optional: true
+
+  '@esbuild/android-arm64@0.23.1':
+    optional: true
+
+  '@esbuild/android-arm@0.23.1':
+    optional: true
+
+  '@esbuild/android-x64@0.23.1':
+    optional: true
+
+  '@esbuild/darwin-arm64@0.23.1':
+    optional: true
+
+  '@esbuild/darwin-x64@0.23.1':
+    optional: true
+
+  '@esbuild/freebsd-arm64@0.23.1':
+    optional: true
+
+  '@esbuild/freebsd-x64@0.23.1':
+    optional: true
+
+  '@esbuild/linux-arm64@0.23.1':
+    optional: true
+
+  '@esbuild/linux-arm@0.23.1':
+    optional: true
+
+  '@esbuild/linux-ia32@0.23.1':
+    optional: true
+
+  '@esbuild/linux-loong64@0.23.1':
+    optional: true
+
+  '@esbuild/linux-mips64el@0.23.1':
+    optional: true
+
+  '@esbuild/linux-ppc64@0.23.1':
+    optional: true
+
+  '@esbuild/linux-riscv64@0.23.1':
+    optional: true
+
+  '@esbuild/linux-s390x@0.23.1':
+    optional: true
+
+  '@esbuild/linux-x64@0.23.1':
+    optional: true
+
+  '@esbuild/netbsd-x64@0.23.1':
+    optional: true
+
+  '@esbuild/openbsd-arm64@0.23.1':
+    optional: true
+
+  '@esbuild/openbsd-x64@0.23.1':
+    optional: true
+
+  '@esbuild/sunos-x64@0.23.1':
+    optional: true
+
+  '@esbuild/win32-arm64@0.23.1':
+    optional: true
+
+  '@esbuild/win32-ia32@0.23.1':
+    optional: true
+
+  '@esbuild/win32-x64@0.23.1':
+    optional: true
+
   '@iarna/toml@2.2.5': {}
 
   '@noble/hashes@1.5.0': {}
@@ -585,6 +825,33 @@ snapshots:
 
   es-errors@1.3.0: {}
 
+  esbuild@0.23.1:
+    optionalDependencies:
+      '@esbuild/aix-ppc64': 0.23.1
+      '@esbuild/android-arm': 0.23.1
+      '@esbuild/android-arm64': 0.23.1
+      '@esbuild/android-x64': 0.23.1
+      '@esbuild/darwin-arm64': 0.23.1
+      '@esbuild/darwin-x64': 0.23.1
+      '@esbuild/freebsd-arm64': 0.23.1
+      '@esbuild/freebsd-x64': 0.23.1
+      '@esbuild/linux-arm': 0.23.1
+      '@esbuild/linux-arm64': 0.23.1
+      '@esbuild/linux-ia32': 0.23.1
+      '@esbuild/linux-loong64': 0.23.1
+      '@esbuild/linux-mips64el': 0.23.1
+      '@esbuild/linux-ppc64': 0.23.1
+      '@esbuild/linux-riscv64': 0.23.1
+      '@esbuild/linux-s390x': 0.23.1
+      '@esbuild/linux-x64': 0.23.1
+      '@esbuild/netbsd-x64': 0.23.1
+      '@esbuild/openbsd-arm64': 0.23.1
+      '@esbuild/openbsd-x64': 0.23.1
+      '@esbuild/sunos-x64': 0.23.1
+      '@esbuild/win32-arm64': 0.23.1
+      '@esbuild/win32-ia32': 0.23.1
+      '@esbuild/win32-x64': 0.23.1
+
   event-stream@3.3.4:
     dependencies:
       duplexer: 0.1.2
@@ -630,6 +897,9 @@ snapshots:
       jsonfile: 6.1.0
       universalify: 2.0.1
 
+  fsevents@2.3.3:
+    optional: true
+
   function-bind@1.1.2: {}
 
   fx@31.0.0: {}
@@ -642,6 +912,10 @@ snapshots:
       has-symbols: 1.0.3
       hasown: 2.0.1
 
+  get-tsconfig@4.8.1:
+    dependencies:
+      resolve-pkg-maps: 1.0.0
+
   glob-parent@5.1.2:
     dependencies:
       is-glob: 4.0.3
@@ -744,6 +1018,8 @@ snapshots:
 
   queue-microtask@1.2.3: {}
 
+  resolve-pkg-maps@1.0.0: {}
+
   reusify@1.0.4: {}
 
   run-parallel@1.2.0:
@@ -775,6 +1051,13 @@ snapshots:
     dependencies:
       is-number: 7.0.0
 
+  tsx@4.19.2:
+    dependencies:
+      esbuild: 0.23.1
+      get-tsconfig: 4.8.1
+    optionalDependencies:
+      fsevents: 2.3.3
+
   typescript@5.5.3: {}
 
   undici-types@5.26.5: {}

+ 1 - 1
scripts/ci/set-env.mjs → scripts/ci/set-env.mts

@@ -1,5 +1,5 @@
 #!/usr/bin/env zx
-import { getSolanaVersion, getToolchain } from '../utils.mjs';
+import { getSolanaVersion, getToolchain } from '../helpers/utils.mts';
 
 await $`echo "SOLANA_VERSION=${getSolanaVersion()}" >> $GITHUB_ENV`;
 await $`echo "TOOLCHAIN_BUILD=${getToolchain('build')}" >> $GITHUB_ENV`;

+ 0 - 30
scripts/client/format-rust.mjs

@@ -1,30 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  partitionArguments,
-  popArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-// Configure additional arguments here, e.g.:
-// ['--arg1', '--arg2', ...cliArguments()]
-const formatArgs = cliArguments();
-
-const fix = popArgument(formatArgs, '--fix');
-const [cargoArgs, fmtArgs] = partitionArguments(formatArgs, '--');
-const toolchain = getToolchainArgument('format');
-const manifestPath = path.join(
-  workingDirectory,
-  'clients',
-  'rust',
-  'Cargo.toml'
-);
-
-// Format the client.
-if (fix) {
-  await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- ${fmtArgs}`;
-} else {
-  await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- --check ${fmtArgs}`;
-}

+ 0 - 24
scripts/client/lint-rust-clippy.mjs

@@ -1,24 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  popArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-// Configure additional arguments here, e.g.:
-// ['--arg1', '--arg2', ...cliArguments()]
-const lintArgs = cliArguments();
-
-const fix = popArgument(lintArgs, '--fix');
-const toolchain = getToolchainArgument('lint');
-const manifestPath = path.join(
-  workingDirectory,
-  'clients',
-  'rust',
-  'Cargo.toml'
-);
-
-// Check the client using Clippy.
-await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} ${fix ? '--fix' : ''} ${lintArgs}`;

+ 0 - 18
scripts/client/lint-rust-docs.mjs

@@ -1,18 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-const args = cliArguments();
-const toolchain = getToolchainArgument('lint');
-const manifestPath = path.join(
-  workingDirectory,
-  'clients',
-  'rust',
-  'Cargo.toml'
-);
-
-await $`RUSTDOCFLAGS="--cfg docsrs -D warnings" cargo ${toolchain} doc --manifest-path ${manifestPath} --all-features --no-deps ${args}`;

+ 0 - 19
scripts/client/lint-rust-features.mjs

@@ -1,19 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-const args = cliArguments();
-const toolchain = getToolchainArgument('lint');
-const manifestPath = path.join(
-  workingDirectory,
-  'clients',
-  'rust',
-  'Cargo.toml'
-);
-
-// Check feature powerset.
-await $`cargo ${toolchain} hack check --manifest-path ${manifestPath} --feature-powerset --all-targets ${args}`;

+ 0 - 17
scripts/client/lint-rust.mjs

@@ -1,17 +0,0 @@
-// Script to lint the Rust client crate.
-//
-// This script runs the following sub-scripts:
-// - lint-rust-clippy.mjs
-// - lint-rust-features.mjs
-// - lint-rust-docs.mjs
-
-import { cliArguments, workingDirectory } from '../utils.mjs';
-
-const scripts = path.join(workingDirectory, 'scripts', 'client');
-
-// clippy
-await $`zx ${path.join(scripts, 'lint-rust-clippy.mjs')}`;
-// features
-await $`zx ${path.join(scripts, 'lint-rust-features.mjs')}`;
-// rustdoc
-await $`zx ${path.join(scripts, 'lint-rust-docs.mjs')}`;

+ 0 - 18
scripts/client/test-rust.mjs

@@ -1,18 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import { cliArguments, workingDirectory } from '../utils.mjs';
-
-// Configure additional arguments here, e.g.:
-// ['--arg1', '--arg2', ...cliArguments()]
-const testArgs = cliArguments();
-
-const hasSolfmt = await which('solfmt', { nothrow: true });
-const sbfOutDir = path.join(workingDirectory, 'target', 'deploy');
-
-// Run the tests.
-cd(path.join(workingDirectory, 'clients', 'rust'));
-if (hasSolfmt) {
-  await $`SBF_OUT_DIR=${sbfOutDir} cargo test --features "test-sbf" ${testArgs} 2>&1 | solfmt`;
-} else {
-  await $`SBF_OUT_DIR=${sbfOutDir} cargo test --features "test-sbf" ${testArgs}`;
-}

+ 1 - 1
scripts/check-solana-version.mjs → scripts/helpers/check-solana-version.mts

@@ -1,6 +1,6 @@
 #!/usr/bin/env zx
 import 'zx/globals';
-import { getInstalledSolanaVersion, getSolanaVersion } from './utils.mjs';
+import { getInstalledSolanaVersion, getSolanaVersion } from './utils.mts';
 
 const expectedVersion = getSolanaVersion();
 const installedVersion = await getInstalledSolanaVersion();

+ 10 - 6
scripts/generate-clients.mjs → scripts/helpers/generate-clients.mts

@@ -3,23 +3,27 @@ import 'zx/globals';
 import { createFromRoot } from 'codama';
 import { renderVisitor as renderJavaScriptVisitor } from '@codama/renderers-js';
 import { renderVisitor as renderRustVisitor } from '@codama/renderers-rust';
-import { workingDirectory } from './utils.mjs';
+import { workingDirectory } from './utils.mts';
 
 // Instanciate Codama.
-const codama = createFromRoot(
-  require(path.join(workingDirectory, 'program', 'idl.json'))
+const idl = JSON.parse(
+  fs.readFileSync(path.join(workingDirectory, 'program', 'idl.json'), 'utf-8')
 );
+const codama = createFromRoot(idl);
 
 // Render JavaScript.
-const jsClient = path.join(__dirname, '..', 'clients', 'js');
+const jsClient = path.join(workingDirectory, 'clients', 'js');
+const prettierOptions = JSON.parse(
+  fs.readFileSync(path.join(jsClient, '.prettierrc.json'), 'utf-8')
+);
 codama.accept(
   renderJavaScriptVisitor(path.join(jsClient, 'src', 'generated'), {
-    prettier: require(path.join(jsClient, '.prettierrc.json')),
+    prettierOptions,
   })
 );
 
 // Render Rust.
-const rustClient = path.join(__dirname, '..', 'clients', 'rust');
+const rustClient = path.join(workingDirectory, 'clients', 'rust');
 codama.accept(
   renderRustVisitor(path.join(rustClient, 'src', 'generated'), {
     formatCode: true,

+ 1 - 1
scripts/link-solana-version.mjs → scripts/helpers/link-solana-version.mts

@@ -1,6 +1,6 @@
 #!/usr/bin/env zx
 import 'zx/globals';
-import { getInstalledSolanaVersion, getSolanaVersion } from './utils.mjs';
+import { getInstalledSolanaVersion, getSolanaVersion } from './utils.mts';
 
 const expectedVersion = getSolanaVersion();
 const installedVersion = await getInstalledSolanaVersion();

+ 7 - 6
scripts/start-validator.mjs → scripts/helpers/start-validator.mts

@@ -8,7 +8,8 @@ import {
   getExternalProgramAddresses,
   getExternalProgramOutputDir,
   getProgramFolders,
-} from './utils.mjs';
+  workingDirectory,
+} from './utils.mts';
 
 // Check Solana version.
 await $`pnpm solana:check`;
@@ -60,7 +61,7 @@ accounts.forEach(({ account, deployPath }) => {
 
 // Start the validator in detached mode.
 const cliLogs = path.join(os.tmpdir(), 'validator-cli.log');
-fs.writeFileSync(cliLogs, '', () => {});
+fs.writeFileSync(cliLogs, '');
 const out = fs.openSync(cliLogs, 'a');
 const err = fs.openSync(cliLogs, 'a');
 const validator = spawn('solana-test-validator', args, {
@@ -79,7 +80,7 @@ const waitForValidator = spinner(
         if (validator.exitCode !== null) {
           reject(logs);
         } else if (logs.includes('Confirmed Slot: 1')) {
-          resolve();
+          resolve(void 0);
         }
       }, 1000);
     })
@@ -97,12 +98,12 @@ try {
 }
 
 function getPrograms() {
-  const binaryDir = path.join(__dirname, '..', 'target', 'deploy');
+  const binaryDir = path.join(workingDirectory, 'target', 'deploy');
   return getProgramFolders().map((folder) => {
     const cargo = getCargo(folder);
-    const name = cargo.package.name.replace(/-/g, '_');
+    const name = cargo.package['name'].replace(/-/g, '_');
     return {
-      programId: cargo.package.metadata.solana['program-id'],
+      programId: cargo.package['metadata'].solana['program-id'],
       deployPath: path.join(binaryDir, `${name}.so`),
     };
   });

+ 0 - 0
scripts/stop-validator.mjs → scripts/helpers/stop-validator.mts


+ 3 - 3
scripts/upgrade-template.mjs → scripts/helpers/upgrade-template.mts

@@ -1,11 +1,11 @@
 #!/usr/bin/env zx
 import 'zx/globals';
-import { getCargo } from './utils.mjs';
+import { getCargo, workingDirectory } from './utils.mts';
 
 // Arguments to pass to the `create-solana-program` command.
 const rustClientCargo = getCargo(path.join('clients', 'rust'));
 const jsClientPkg = require(
-  path.join(__dirname, '..', 'clients', 'js', 'package.json')
+  path.join(workingDirectory, 'clients', 'js', 'package.json')
 );
 const templateArgs = [
   'system',
@@ -14,7 +14,7 @@ const templateArgs = [
   '--org',
   'solana-program',
   '--rust-client-crate-name',
-  rustClientCargo.package.name,
+  rustClientCargo.package['name'],
   '--js-client-package-name',
   jsClientPkg.name,
   '--default',

+ 41 - 21
scripts/utils.mjs → scripts/helpers/utils.mts

@@ -1,30 +1,30 @@
 import 'zx/globals';
-import { parse as parseToml } from '@iarna/toml';
+import { JsonMap, parse as parseToml } from '@iarna/toml';
 
-process.env.FORCE_COLOR = 3;
+process.env.FORCE_COLOR = '3';
 process.env.CARGO_TERM_COLOR = 'always';
 
 export const workingDirectory = (await $`pwd`.quiet()).toString().trim();
 
-export function getAllProgramIdls() {
+export function getAllProgramIdls(): string[] {
   return getAllProgramFolders().map((folder) =>
     path.join(workingDirectory, folder, 'idl.json')
   );
 }
 
-export function getExternalProgramOutputDir() {
+export function getExternalProgramOutputDir(): string {
   const config = getCargoMetadata()?.solana?.['external-programs-output'];
   return path.join(workingDirectory, config ?? 'target/deploy');
 }
 
-export function getExternalProgramAddresses() {
+export function getExternalProgramAddresses(): string[] {
   const addresses = getProgramFolders().flatMap(
     (folder) => getCargoMetadata(folder)?.solana?.['program-dependencies'] ?? []
   );
   return Array.from(new Set(addresses));
 }
 
-export function getExternalAccountAddresses() {
+export function getExternalAccountAddresses(): string[] {
   const addresses = getProgramFolders().flatMap(
     (folder) => getCargoMetadata(folder)?.solana?.['account-dependencies'] ?? []
   );
@@ -32,7 +32,7 @@ export function getExternalAccountAddresses() {
 }
 
 let didWarnAboutMissingPrograms = false;
-export function getProgramFolders() {
+export function getProgramFolders(): string[] {
   let programs;
 
   if (process.env.PROGRAMS) {
@@ -64,13 +64,13 @@ export function getProgramFolders() {
   return filteredPrograms;
 }
 
-export function getAllProgramFolders() {
-  return getCargo().workspace.members.filter((member) =>
-    getCargo(member).package?.metadata?.solana?.['program-id']
+export function getAllProgramFolders(): string[] {
+  return getCargo().workspace['members'].filter(
+    (member) => getCargo(member).package['metadata']?.['solana']?.['program-id']
   );
 }
 
-export function getCargo(folder) {
+export function getCargo(folder?: string): JsonMap {
   return parseToml(
     fs.readFileSync(
       path.join(workingDirectory, folder ? folder : '.', 'Cargo.toml'),
@@ -79,29 +79,29 @@ export function getCargo(folder) {
   );
 }
 
-export function getCargoMetadata(folder) {
+export function getCargoMetadata(folder?: string) {
   const cargo = getCargo(folder);
-  return folder ? cargo?.package?.metadata : cargo?.workspace?.metadata;
+  return folder ? cargo?.package?.['metadata'] : cargo?.workspace?.['metadata'];
 }
 
-export function getSolanaVersion() {
+export function getSolanaVersion(): string {
   return getCargoMetadata()?.cli?.solana;
 }
 
-export function getToolchain(operation) {
+export function getToolchain(operation): string {
   return getCargoMetadata()?.toolchains?.[operation];
 }
 
-export function getToolchainArgument(operation) {
+export function getToolchainArgument(operation): string {
   const channel = getToolchain(operation);
   return channel ? `+${channel}` : '';
 }
 
-export function cliArguments() {
-  return process.argv.slice(3);
+export function cliArguments(): string[] {
+  return process.argv.slice(2);
 }
 
-export function popArgument(args, arg) {
+export function popArgument(args: string[], arg: string) {
   const index = args.indexOf(arg);
   if (index >= 0) {
     args.splice(index, 1);
@@ -109,14 +109,17 @@ export function popArgument(args, arg) {
   return index >= 0;
 }
 
-export function partitionArguments(args, delimiter) {
+export function partitionArguments(
+  args: string[],
+  delimiter: string
+): [string[], string[]] {
   const index = args.indexOf(delimiter);
   return index >= 0
     ? [args.slice(0, index), args.slice(index + 1)]
     : [args, []];
 }
 
-export async function getInstalledSolanaVersion() {
+export async function getInstalledSolanaVersion(): Promise<string | undefined> {
   try {
     const { stdout } = await $`solana --version`.quiet();
     return stdout.match(/(\d+\.\d+\.\d+)/)?.[1];
@@ -124,3 +127,20 @@ export async function getInstalledSolanaVersion() {
     return '';
   }
 }
+
+export function parseCliArguments(): { manifestPath: string; args: string[] } {
+  // Command-line arguments.
+  const args = cliArguments();
+  // Extract the relative crate directory from the command-line arguments. This
+  // is the only required argument.
+  const relativePath = args.shift();
+
+  if (!relativePath) {
+    throw new Error('Missing relative manifest path');
+  }
+
+  return {
+    manifestPath: path.join(workingDirectory, relativePath, 'Cargo.toml'),
+    args,
+  };
+}

+ 0 - 25
scripts/interface/format.mjs

@@ -1,25 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  partitionArguments,
-  popArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-// Configure additional arguments here, e.g.:
-// ['--arg1', '--arg2', ...cliArguments()]
-const formatArgs = cliArguments();
-
-const fix = popArgument(formatArgs, '--fix');
-const [cargoArgs, fmtArgs] = partitionArguments(formatArgs, '--');
-const toolchain = getToolchainArgument('format');
-const manifestPath = path.join(workingDirectory, 'interface', 'Cargo.toml');
-
-// Format the interface.
-if (fix) {
-  await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- ${fmtArgs}`;
-} else {
-  await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- --check ${fmtArgs}`;
-}

+ 0 - 35
scripts/interface/lint-clippy.mjs

@@ -1,35 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  popArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-// Configure additional arguments here, e.g.:
-// ['--arg1', '--arg2', ...cliArguments()]
-const lintArgs = ['--all-targets', '--all-features', ...cliArguments()];
-// Check whether a '--' was already used.
-if (lintArgs.indexOf('--') === -1) {
-  lintArgs.push('--');
-}
-// Add additional arguments.
-lintArgs.push(
-  '--deny=warnings',
-  '--deny=clippy::default_trait_access',
-  '--deny=clippy::arithmetic_side_effects',
-  '--deny=clippy::manual_let_else',
-  '--deny=clippy::used_underscore_binding'
-);
-
-const fix = popArgument(lintArgs, '--fix');
-// Note: need to use nightly clippy as frozen-abi proc-macro generates
-// a lot of code (frozen-abi is enabled only under nightly due to the
-// use of unstable rust feature). Likewise, frozen-abi(-macro) crates'
-// unit tests are only compiled under nightly.
-const toolchain = getToolchainArgument('lint');
-const manifestPath = path.join(workingDirectory, 'interface', 'Cargo.toml');
-
-// Lint the interface.
-await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} ${fix ? '--fix' : ''} ${lintArgs}`;

+ 0 - 13
scripts/interface/lint-docs.mjs

@@ -1,13 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-const args = cliArguments();
-const toolchain = getToolchainArgument('lint');
-const manifestPath = path.join(workingDirectory, 'interface', 'Cargo.toml');
-
-await $`RUSTDOCFLAGS="--cfg docsrs -D warnings" cargo ${toolchain} doc --manifest-path ${manifestPath} --all-features --no-deps ${args}`;

+ 0 - 14
scripts/interface/lint-features.mjs

@@ -1,14 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-const args = ['--exclude-features', 'frozen-abi', ...cliArguments()];
-const toolchain = getToolchainArgument('lint');
-const manifestPath = path.join(workingDirectory, 'interface', 'Cargo.toml');
-
-// Check feature powerset.
-await $`cargo ${toolchain} hack check --manifest-path ${manifestPath} --feature-powerset --all-targets ${args}`;

+ 0 - 17
scripts/interface/lint.mjs

@@ -1,17 +0,0 @@
-// Script to lint the interface crate.
-//
-// This script runs the following sub-scripts:
-// - lint-clippy.mjs
-// - lint-features.mjs
-// - lint-docs.mjs
-
-import { workingDirectory } from '../utils.mjs';
-
-const scripts = path.join(workingDirectory, 'scripts', 'interface');
-
-// clippy
-await $`zx ${path.join(scripts, 'lint-clippy.mjs')}`;
-// features
-await $`zx ${path.join(scripts, 'lint-features.mjs')}`;
-// rustdoc
-await $`zx ${path.join(scripts, 'lint-docs.mjs')}`;

+ 0 - 16
scripts/interface/test.mjs

@@ -1,16 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  getToolchainArgument,
-  workingDirectory,
-} from '../utils.mjs';
-
-// Configure additional arguments here, e.g.:
-// ['--arg1', '--arg2', ...cliArguments()]
-const buildArgs = cliArguments();
-const toolchain = getToolchainArgument('test');
-const manifestPath = path.join(workingDirectory, 'interface', 'Cargo.toml');
-
-// Test the interface.
-await $`cargo ${toolchain} test --all-features --manifest-path ${manifestPath} ${buildArgs}`;

+ 0 - 14
scripts/interface/wasm.mjs

@@ -1,14 +0,0 @@
-#!/usr/bin/env zx
-import 'zx/globals';
-import {
-  cliArguments,
-  workingDirectory,
-} from '../utils.mjs';
-
-// Configure additional arguments here, e.g.:
-// ['--arg1', '--arg2', ...cliArguments()]
-const buildArgs = cliArguments();
-const cratePath = path.join(workingDirectory, 'interface');
-
-// Build the interface.
-await $`wasm-pack build --target nodejs --dev ${cratePath} --features bincode ${buildArgs}`;

+ 1 - 1
scripts/client/format-js.mjs → scripts/js/format.mts

@@ -1,6 +1,6 @@
 #!/usr/bin/env zx
 import 'zx/globals';
-import { cliArguments, workingDirectory } from '../utils.mjs';
+import { cliArguments, workingDirectory } from '../helpers/utils.mts';
 
 // Format the client using Prettier.
 cd(path.join(workingDirectory, 'clients', 'js'));

+ 1 - 1
scripts/client/lint-js.mjs → scripts/js/lint.mts

@@ -1,6 +1,6 @@
 #!/usr/bin/env zx
 import 'zx/globals';
-import { cliArguments, workingDirectory } from '../utils.mjs';
+import { cliArguments, workingDirectory } from '../helpers/utils.mts';
 
 // Check the client using ESLint.
 cd(path.join(workingDirectory, 'clients', 'js'));

+ 1 - 1
scripts/client/publish-js.mjs → scripts/js/publish.mts

@@ -1,6 +1,6 @@
 #!/usr/bin/env zx
 import 'zx/globals';
-import { cliArguments, workingDirectory } from '../utils.mjs';
+import { cliArguments, workingDirectory } from '../helpers/utils.mts';
 
 const [level, tag = 'latest'] = cliArguments();
 if (!level) {

+ 1 - 1
scripts/client/test-js.mjs → scripts/js/test.mts

@@ -1,6 +1,6 @@
 #!/usr/bin/env zx
 import 'zx/globals';
-import { cliArguments, workingDirectory } from '../utils.mjs';
+import { cliArguments, workingDirectory } from '../helpers/utils.mts';
 
 // Start the local validator, or restart it if it is already running.
 await $`pnpm validator:restart`;

+ 20 - 0
scripts/rust/format.mts

@@ -0,0 +1,20 @@
+#!/usr/bin/env zx
+import 'zx/globals';
+import {
+  getToolchainArgument,
+  parseCliArguments,
+  partitionArguments,
+  popArgument,
+} from '../helpers/utils.mts';
+
+// Extract the crate directory from the command-line arguments.
+const { manifestPath, args } = parseCliArguments();
+// Configure additional arguments here, e.g.:
+// ['--arg1', '--arg2', ...args]
+const formatArgs = args;
+
+const fix = popArgument(args, '--fix');
+const [cargoArgs, fmtArgs] = partitionArguments(formatArgs, '--');
+const toolchain = getToolchainArgument('format');
+
+await $`cargo ${toolchain} fmt --manifest-path ${manifestPath} ${cargoArgs} -- ${fix ? '' : '--check'} ${fmtArgs}`;

+ 22 - 0
scripts/rust/lint-clippy.mts

@@ -0,0 +1,22 @@
+#!/usr/bin/env zx
+import 'zx/globals';
+import {
+  getToolchainArgument,
+  parseCliArguments,
+  popArgument,
+} from '../helpers/utils.mts';
+
+// Extract the crate directory from the command-line arguments.
+const { manifestPath, args } = parseCliArguments();
+// Configure additional arguments here, e.g.:
+// ['--arg1', '--arg2', ...args]
+const clippyArgs = args;
+// Note: need to use nightly clippy as frozen-abi proc-macro generates
+// a lot of code (frozen-abi is enabled only under nightly due to the
+// use of unstable rust feature). Likewise, frozen-abi(-macro) crates'
+// unit tests are only compiled under nightly.
+const toolchain = getToolchainArgument('lint');
+// Check if the `--fix` argument is present.
+const fix = popArgument(clippyArgs, '--fix');
+
+await $`cargo ${toolchain} clippy --manifest-path ${manifestPath} ${fix ? '--fix' : ''} ${clippyArgs}`;

+ 12 - 0
scripts/rust/lint-docs.mts

@@ -0,0 +1,12 @@
+#!/usr/bin/env zx
+import 'zx/globals';
+import { getToolchainArgument, parseCliArguments } from '../helpers/utils.mts';
+
+// Extract the crate directory from the command-line arguments.
+const { manifestPath, args } = parseCliArguments();
+// Configure additional arguments here, e.g.:
+// ['--arg1', '--arg2', ...args]
+const docArgs = args;
+const toolchain = getToolchainArgument('lint');
+
+await $`RUSTDOCFLAGS="--cfg docsrs -D warnings" cargo ${toolchain} doc --manifest-path ${manifestPath} --all-features --no-deps ${docArgs}`;

+ 13 - 0
scripts/rust/lint-features.mts

@@ -0,0 +1,13 @@
+#!/usr/bin/env zx
+import 'zx/globals';
+import { getToolchainArgument, parseCliArguments } from '../helpers/utils.mts';
+
+// Extract the crate directory from the command-line arguments.
+const { manifestPath, args } = parseCliArguments();
+// Configure additional arguments here, e.g.:
+// ['--arg1', '--arg2', ...args]
+const featuresArgs = ['--exclude-features', 'frozen-abi', ...args];
+const toolchain = getToolchainArgument('lint');
+
+// Check feature powerset.
+await $`cargo ${toolchain} hack check --manifest-path ${manifestPath} --feature-powerset --all-targets ${featuresArgs}`;

+ 17 - 0
scripts/rust/lint.mts

@@ -0,0 +1,17 @@
+// Script to lint a crate.
+//
+// This script runs the following sub-scripts:
+// - lint-clippy.mjs
+// - lint-docs.mjs
+// - lint-features.mjs
+
+import { cliArguments, workingDirectory } from '../helpers/utils.mts';
+
+const scripts = path.join(workingDirectory, 'scripts', 'rust');
+
+// clippy
+await $`tsx ${path.join(scripts, 'lint-clippy.mjs')} ${cliArguments()}`;
+// rustdoc
+await $`tsx ${path.join(scripts, 'lint-docs.mjs')} ${cliArguments()}`;
+// features
+await $`tsx ${path.join(scripts, 'lint-features.mjs')} ${cliArguments()}`;

+ 12 - 7
scripts/client/publish-rust.mjs → scripts/rust/publish.mts

@@ -1,15 +1,18 @@
 #!/usr/bin/env zx
 import 'zx/globals';
-import { cliArguments, getCargo, workingDirectory } from '../utils.mjs';
+import { getCargo, parseCliArguments } from '../helpers/utils.mts';
+
+// Extract the crate directory from the command-line arguments.
+const { manifestPath, args } = parseCliArguments();
 
 const dryRun = argv['dry-run'] ?? false;
-const [level] = cliArguments();
+const [level] = args;
 if (!level) {
   throw new Error('A version level — e.g. "path" — must be provided.');
 }
 
 // Go to the client directory and install the dependencies.
-cd(path.join(workingDirectory, 'clients', 'rust'));
+cd(path.dirname(manifestPath));
 
 // Publish the new version.
 const releaseArgs = dryRun
@@ -22,8 +25,10 @@ if (dryRun) {
   process.exit(0);
 }
 
-// Get the new version.
-const newVersion = getCargo(path.join('clients', 'rust')).package.version;
+// Get the crate information.
+const toml = getCargo(path.dirname(manifestPath));
+const crateName = toml.package['name'];
+const newVersion = toml.package['version'];
 
 // Expose the new version to CI if needed.
 if (process.env.CI) {
@@ -34,7 +39,7 @@ if (process.env.CI) {
 await $`git reset --soft HEAD~1`;
 
 // Commit the new version.
-await $`git commit -am "Publish Rust client v${newVersion}"`;
+await $`git commit -am "Publish ${crateName} v${newVersion}"`;
 
 // Tag the new version.
-await $`git tag -a rust@v${newVersion} -m "Rust client v${newVersion}"`;
+await $`git tag -a ${crateName}@v${newVersion} -m "${crateName} v${newVersion}"`;

+ 25 - 0
scripts/rust/test.mts

@@ -0,0 +1,25 @@
+#!/usr/bin/env zx
+import 'zx/globals';
+import {
+  getToolchainArgument,
+  parseCliArguments,
+  workingDirectory,
+} from '../helpers/utils.mts';
+
+// Extract the crate directory from the command-line arguments.
+const { manifestPath, args } = parseCliArguments();
+// Configure additional arguments here, e.g.:
+// ['--arg1', '--arg2', ...args]
+const testArgs = args;
+
+const toolchain = getToolchainArgument('test');
+
+const hasSolfmt = await which('solfmt', { nothrow: true });
+const sbfOutDir = path.join(workingDirectory, 'target', 'deploy');
+
+// Run the tests.
+if (hasSolfmt) {
+  await $`SBF_OUT_DIR=${sbfOutDir} cargo ${toolchain} test --all-features --manifest-path ${manifestPath} ${testArgs} >&1 | solfmt`;
+} else {
+  await $`SBF_OUT_DIR=${sbfOutDir} cargo ${toolchain} test --all-features --manifest-path ${manifestPath} ${testArgs}`;
+}

+ 11 - 0
scripts/rust/wasm.mts

@@ -0,0 +1,11 @@
+#!/usr/bin/env zx
+import 'zx/globals';
+import { parseCliArguments } from '../helpers/utils.mts';
+
+// Extract the crate directory from the command-line arguments.
+const { manifestPath, args } = parseCliArguments();
+// Configure additional arguments here, e.g.:
+// ['--arg1', '--arg2', ...args]
+const wasmArgs = args;
+
+await $`wasm-pack build --target nodejs --dev ${path.dirname(manifestPath)} --features bincode ${wasmArgs}`;