Compare commits
184 Commits
pierremtb/
...
nightly-v2
Author | SHA1 | Date | |
---|---|---|---|
aca5fdb521 | |||
8867258e47 | |||
f6cb725268 | |||
1bd570ceb9 | |||
1c87298b44 | |||
3a23ec1bee | |||
d96a4d3337 | |||
94452cce88 | |||
2e754f2a11 | |||
719136937e | |||
e207552255 | |||
1835e49191 | |||
145c28bbd5 | |||
a58a3361b6 | |||
efba773635 | |||
4439229ad2 | |||
0dcb8baf64 | |||
921adcb3eb | |||
24465cf463 | |||
d0b0365f75 | |||
0f88598dc0 | |||
d7e80b3cc7 | |||
25bb95a66e | |||
6e115c19d5 | |||
5a18f551aa | |||
0426967bf7 | |||
9d893d8f0b | |||
8de648f0db | |||
50f8131d83 | |||
5a4f8bd522 | |||
f8e53d941d | |||
717a2039cb | |||
6e7c44fca7 | |||
ffbe20b586 | |||
9547e95e9d | |||
a1f31f4348 | |||
604e244395 | |||
fe22a67cf6 | |||
885d2afaa3 | |||
be4a32a59e | |||
c501d3bfbf | |||
0ef1483e11 | |||
bbaaf86e4d | |||
6a0e10f8ab | |||
5c0ca52291 | |||
bff13f6bfe | |||
6001b71f06 | |||
bd1e68a4c8 | |||
8589f8fc5f | |||
6641e1178b | |||
6e0f1e71b2 | |||
0e945b6457 | |||
19155a9132 | |||
305d613d40 | |||
95f2caacab | |||
8f61ee1d2f | |||
b02dbd4fe6 | |||
668f6671a9 | |||
f6387eb7e9 | |||
83a87b046f | |||
20c2ce3bac | |||
2956f9ed55 | |||
510d74f2c7 | |||
457ab28f74 | |||
1502f923ee | |||
f03a684eec | |||
45e17c50e7 | |||
6bf74379a7 | |||
01c6fd53fa | |||
f8306c0275 | |||
900ef9e18d | |||
a46186573c | |||
90f6c1bb04 | |||
41d946b339 | |||
b7385d5f25 | |||
3d22f6cd66 | |||
9730e3f5b3 | |||
29d6b22d63 | |||
f99e44e371 | |||
8be36d3d16 | |||
bc1742af48 | |||
e4080cc184 | |||
18de6ccb59 | |||
f00ea4cf5e | |||
c5539be814 | |||
f5d6a12d8c | |||
e4e18dfd4b | |||
30ee547ce4 | |||
f8ca6ad746 | |||
7a90d029e1 | |||
2900858171 | |||
0dee219e46 | |||
790613e708 | |||
0a35722595 | |||
f30fc376ee | |||
8c1a95833d | |||
4f1ba1be01 | |||
90acc00369 | |||
e4fe8a4440 | |||
fbc3251c3f | |||
a0f3f0f50e | |||
dad0d5488f | |||
77773fb052 | |||
1240ca6f21 | |||
ce3a6ad286 | |||
a20f420a55 | |||
03c4121ab7 | |||
8c2c877817 | |||
c77bb92da9 | |||
bd4bad0020 | |||
0b9889e313 | |||
f9fbaa2298 | |||
6f2d127c4f | |||
056a4d4a22 | |||
bab79331cb | |||
16bbc970ae | |||
0f1cff316c | |||
938a2bae13 | |||
3324835b72 | |||
1628ea86b2 | |||
be119248a6 | |||
ac75181f7f | |||
d9fe78171f | |||
5586646a60 | |||
e955e783f4 | |||
9162c4d723 | |||
f345a07bcd | |||
f5e3b4bbe7 | |||
941911ed30 | |||
599bd2d958 | |||
a847c7f608 | |||
d9be308c36 | |||
3cca4a30af | |||
c51db5bd4a | |||
7fce38b212 | |||
d0e9b111af | |||
add1b21503 | |||
39af110ac1 | |||
bf7ec424a7 | |||
6c7e42b541 | |||
542a9a3f13 | |||
264779a9d0 | |||
22dd4a67dd | |||
5c188664bd | |||
f6e23fe619 | |||
160f55ede5 | |||
7d7b153085 | |||
8f487a441b | |||
c8cee6a0dc | |||
167445ef8a | |||
95b72d839b | |||
9365186bed | |||
eea026f8e0 | |||
3cd7a3533e | |||
9e1f1152e3 | |||
60d2be9ff2 | |||
0f59894d66 | |||
74c07fc0eb | |||
67a8bf525d | |||
129b91518f | |||
c0aa763c3b | |||
319c60d4fa | |||
66f95d25f6 | |||
72ab72cea1 | |||
4e1e9f9c6e | |||
8b14d32879 | |||
7c5170dc16 | |||
a07dbc3aac | |||
7d3294ff78 | |||
121c393466 | |||
c6ec54c138 | |||
1f6b90d383 | |||
c45c2e27ba | |||
5832890dbb | |||
6f2e6d14b6 | |||
0d899694b2 | |||
7bd5e7365d | |||
a63e51e2ad | |||
1b8eee86a1 | |||
6d50278d34 | |||
35844842de | |||
843e772094 | |||
9d0518dfeb | |||
d33d399c31 |
@ -1,3 +1,3 @@
|
||||
[codespell]
|
||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser,fromM,FromM
|
||||
skip: **/target,node_modules,build,dist,./out,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock,./openapi/*.json,./packages/codemirror-lang-kcl/test/all.test.ts,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo
|
||||
skip: **/target,node_modules,build,dist,./out,**/Cargo.lock,./docs/kcl/*.md,./e2e/playwright/lib/console-error-whitelist.ts,.package-lock.json,**/package-lock.json,./openapi/*.json,./packages/codemirror-lang-kcl/test/all.test.ts,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo,./src/lib/machine-api.d.ts
|
||||
|
@ -19,6 +19,11 @@
|
||||
"plugin:jsx-a11y/recommended",
|
||||
"plugin:react-hooks/recommended"
|
||||
],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
|
||||
"@typescript-eslint/no-array-constructor": "error",
|
||||
@ -61,6 +66,7 @@
|
||||
"jsx-a11y/click-events-have-key-events": "off",
|
||||
"jsx-a11y/no-autofocus": "off",
|
||||
"jsx-a11y/no-noninteractive-element-interactions": "off",
|
||||
"react/no-unknown-property": "error",
|
||||
"no-restricted-globals": [
|
||||
"error",
|
||||
{
|
||||
|
23
.github/ci-cd-scripts/playwright-electron.sh
vendored
23
.github/ci-cd-scripts/playwright-electron.sh
vendored
@ -7,11 +7,11 @@ if [[ ! -f "test-results/.last-run.json" ]]; then
|
||||
# If no last run artifact, than run Playwright normally
|
||||
echo "run playwright normally"
|
||||
if [[ "$3" == *ubuntu* ]]; then
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:playwright:electron:ubuntu -- --shard=$1/$2 || true
|
||||
elif [[ "$3" == *windows* ]]; then
|
||||
yarn test:playwright:electron:windows -- --shard=$1/$2 || true
|
||||
npm run test:playwright:electron:windows -- --shard=$1/$2 || true
|
||||
elif [[ "$3" == *macos* ]]; then
|
||||
yarn test:playwright:electron:macos -- --shard=$1/$2 || true
|
||||
npm run test:playwright:electron:macos -- --shard=$1/$2 || true
|
||||
else
|
||||
echo "Do not run Playwright. Unable to detect os runtime."
|
||||
exit 1
|
||||
@ -26,16 +26,16 @@ max_retries=1
|
||||
# Retry failed tests, doing our own retries because using inbuilt Playwright retries causes connection issues
|
||||
while [[ $retry -le $max_retries ]]; do
|
||||
if [[ -f "test-results/.last-run.json" ]]; then
|
||||
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
|
||||
if [[ $failed_tests -gt 0 ]]; then
|
||||
status=$(jq -r '.status' test-results/.last-run.json)
|
||||
if [[ "$status" == "failed" ]]; then
|
||||
echo "retried=true" >>$GITHUB_OUTPUT
|
||||
echo "run playwright with last failed tests and retry $retry"
|
||||
if [[ "$3" == *ubuntu* ]]; then
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --last-failed || true
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:playwright:electron:ubuntu -- --last-failed || true
|
||||
elif [[ "$3" == *windows* ]]; then
|
||||
yarn test:playwright:electron:windows -- --last-failed || true
|
||||
npm run test:playwright:electron:windows -- --last-failed || true
|
||||
elif [[ "$3" == *macos* ]]; then
|
||||
yarn test:playwright:electron:macos -- --last-failed || true
|
||||
npm run test:playwright:electron:macos -- --last-failed || true
|
||||
else
|
||||
echo "Do not run playwright. Unable to detect os runtime."
|
||||
exit 1
|
||||
@ -56,10 +56,11 @@ done
|
||||
echo "retried=false" >>$GITHUB_OUTPUT
|
||||
|
||||
if [[ -f "test-results/.last-run.json" ]]; then
|
||||
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
|
||||
if [[ $failed_tests -gt 0 ]]; then
|
||||
# If it still fails after 3 retries, then fail the job
|
||||
status=$(jq -r '.status' test-results/.last-run.json)
|
||||
if [[ "$status" == "failed" ]]; then
|
||||
# If it still fails after retries, then fail the job
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
6
.github/workflows/build-and-store-wasm.yml
vendored
6
.github/workflows/build-and-store-wasm.yml
vendored
@ -13,9 +13,9 @@ jobs:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
run: npm install
|
||||
- name: Use correct Rust toolchain
|
||||
shell: bash
|
||||
run: |
|
||||
@ -32,7 +32,7 @@ jobs:
|
||||
with:
|
||||
workspaces: rust
|
||||
- name: build wasm
|
||||
run: yarn build:wasm
|
||||
run: npm run build:wasm
|
||||
|
||||
|
||||
# Upload the WASM bundle as an artifact
|
||||
|
56
.github/workflows/build-apps.yml
vendored
56
.github/workflows/build-apps.yml
vendored
@ -29,9 +29,9 @@ jobs:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- run: yarn install
|
||||
- run: npm install
|
||||
|
||||
- id: filter
|
||||
name: Check for Rust changes
|
||||
@ -90,20 +90,20 @@ jobs:
|
||||
|
||||
- name: Run build:wasm
|
||||
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||
run: "yarn build:wasm"
|
||||
run: "npm run build:wasm"
|
||||
|
||||
- name: Set nightly version, product name, release notes, and icons
|
||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||
run: |
|
||||
export VERSION=${GITHUB_REF_NAME#nightly-v}
|
||||
yarn files:set-version
|
||||
yarn files:flip-to-nightly
|
||||
npm run files:set-version
|
||||
npm run files:flip-to-nightly
|
||||
|
||||
- name: Set release version
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
run: |
|
||||
export VERSION=${GITHUB_REF_NAME#v}
|
||||
yarn files:set-version
|
||||
npm run files:set-version
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@ -172,16 +172,9 @@ jobs:
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn' # Set this to npm, yarn or pnpm.
|
||||
cache: 'npm' # Set this to npm, npm or pnpm.
|
||||
|
||||
- name: yarn install
|
||||
# Windows is picky sometimes and fails on fetch. Step takes about ~30s
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 2
|
||||
max_attempts: 3
|
||||
command: yarn install
|
||||
- run: npm install
|
||||
|
||||
- name: Prepare certificate and variables (Windows only)
|
||||
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
||||
@ -207,13 +200,20 @@ jobs:
|
||||
smctl.exe keypair ls
|
||||
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
|
||||
smksp_cert_sync.exe
|
||||
smctl windows certsync
|
||||
# This last line `smctl windows certsync` was added after windows codesign failures started happening
|
||||
# with nightly-v25.4.10. It looks like `smksp_cert_sync.exe` used to do the sync to the local cert store,
|
||||
# but stopped doing it overnight. This extra call that I randomly got from this azure-related doc page
|
||||
# https://docs.digicert.com/en/digicert-keylocker/code-signing/sign-with-third-party-signing-tools/windows-applications/sign-azure-apps-with-signtool-using-ksp-library.html#sync-certificates--windows-only--618365
|
||||
# seems to be doing that extra sync that we need for scripts/sign-win.js to work.
|
||||
# TODO: we still need to make sign-win.js errors fail the workflow, see issue #6276
|
||||
shell: cmd
|
||||
|
||||
- name: Build the app (debug)
|
||||
if: ${{ env.IS_RELEASE == 'false' && env.IS_NIGHTLY == 'false' }}
|
||||
# electron-builder doesn't have a concept of release vs debug,
|
||||
# this is just not doing any codesign or release yml generation, and points to dev infra
|
||||
run: yarn tronb:package:dev
|
||||
run: npm run tronb:package:dev
|
||||
|
||||
- name: Build the app (release)
|
||||
if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
|
||||
@ -226,14 +226,7 @@ jobs:
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||
DEBUG: "electron-notarize*"
|
||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: yarn tronb:package:prod
|
||||
run: npm run tronb:package:prod
|
||||
|
||||
- name: List artifacts in out/
|
||||
run: ls -R out
|
||||
@ -288,14 +281,7 @@ jobs:
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||
DEBUG: "electron-notarize*"
|
||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: yarn tronb:package:prod
|
||||
run: npm run tronb:package:prod
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
@ -378,7 +364,7 @@ jobs:
|
||||
NOTES: ${{ needs.prepare-files.outputs.notes }}
|
||||
PUB_DATE: ${{ github.event.repository.updated_at }}
|
||||
WEBSITE_DIR: ${{ env.IS_NIGHTLY == 'true' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
|
||||
URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
|
||||
URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Design%20Studio%20%28Nightly%29' || 'Zoo%20Design%20Studio' }}
|
||||
run: |
|
||||
RELEASE_DIR=https://${WEBSITE_DIR}
|
||||
jq --null-input \
|
||||
@ -435,7 +421,7 @@ jobs:
|
||||
export TAG="nightly-${VERSION}"
|
||||
export PREVIOUS_TAG=$(git tag --list --sort=-committerdate "nightly-v[0-9]*" | head -n2 | tail -n1)
|
||||
export NOTES=$(./scripts/get-nightly-changelog.sh)
|
||||
yarn files:set-notes
|
||||
npm run files:set-notes
|
||||
|
||||
- name: Authenticate to Google Cloud
|
||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||
@ -460,4 +446,4 @@ jobs:
|
||||
|
||||
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||
run: yarn files:invalidate-bucket:nightly
|
||||
run: npm run files:invalidate-bucket:nightly
|
||||
|
9
.github/workflows/cargo-bench.yml
vendored
9
.github/workflows/cargo-bench.yml
vendored
@ -26,12 +26,8 @@ name: cargo bench
|
||||
jobs:
|
||||
cargo-bench:
|
||||
name: cargo bench
|
||||
runs-on:
|
||||
- runs-on=${{ github.run_id }}
|
||||
- runner=32cpu-linux-x64
|
||||
- extras=s3-cache
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use correct Rust toolchain
|
||||
shell: bash
|
||||
@ -50,13 +46,12 @@ jobs:
|
||||
- name: Build the benchmark target(s)
|
||||
run: |
|
||||
cd rust
|
||||
cargo codspeed build --measurement-mode walltime
|
||||
cargo codspeed build
|
||||
- name: Run the benchmarks
|
||||
uses: CodSpeedHQ/action@v3
|
||||
with:
|
||||
working-directory: rust
|
||||
run: cargo codspeed run
|
||||
token: ${{ secrets.CODSPEED_TOKEN }}
|
||||
mode: walltime
|
||||
env:
|
||||
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN }}
|
||||
|
13
.github/workflows/cargo-test.yml
vendored
13
.github/workflows/cargo-test.yml
vendored
@ -15,8 +15,12 @@ name: cargo test
|
||||
jobs:
|
||||
cargotest:
|
||||
name: cargo test
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
runs-on:
|
||||
- runs-on=${{ github.run_id }}
|
||||
- runner=32cpu-linux-x64
|
||||
- extras=s3-cache
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
@ -81,11 +85,10 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd rust
|
||||
cargo nextest run --workspace --retries=2 --no-fail-fast --profile ci simulation_tests::kcl_samples 2>&1 | tee /tmp/github-actions.log
|
||||
cargo nextest run --workspace --features artifact-graph --retries=2 --no-fail-fast --profile ci simulation_tests::kcl_samples 2>&1 | tee /tmp/github-actions.log
|
||||
env:
|
||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
|
||||
RUST_BACKTRACE: full
|
||||
RUST_MIN_STACK: 10485760000
|
||||
- name: Commit differences
|
||||
if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure'
|
||||
shell: bash
|
||||
@ -118,16 +121,14 @@ jobs:
|
||||
# Configure nextest when it's run by insta (via just).
|
||||
NEXTEST_PROFILE: ci
|
||||
RUST_BACKTRACE: full
|
||||
RUST_MIN_STACK: 10485760000
|
||||
- name: cargo test
|
||||
if: steps.path-changes.outputs.outside-kcl-samples == 'true'
|
||||
shell: bash
|
||||
run: |-
|
||||
cd rust
|
||||
cargo llvm-cov nextest --workspace --lcov --output-path lcov.info --retries=2 --no-fail-fast -P ci 2>&1 | tee /tmp/github-actions.log
|
||||
cargo llvm-cov nextest --workspace --features artifact-graph --lcov --output-path lcov.info --retries=2 --no-fail-fast -P ci 2>&1 | tee /tmp/github-actions.log
|
||||
env:
|
||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
|
||||
RUST_MIN_STACK: 10485760000
|
||||
- name: Upload to codecov.io
|
||||
if: steps.path-changes.outputs.outside-kcl-samples == 'true'
|
||||
uses: codecov/codecov-action@v5
|
||||
|
7
.github/workflows/check-exampleKcl.yml
vendored
7
.github/workflows/check-exampleKcl.yml
vendored
@ -5,6 +5,7 @@ on:
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- 'src/lib/exampleKcl.ts'
|
||||
- 'public/kcl-samples/bracket/main.kcl'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@ -22,11 +23,11 @@ jobs:
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const message = '`src/lib/exampleKcl.ts` has been updated in this PR, please review and update the `src/routes/onboarding`, if needed.';
|
||||
const message = '`public/kcl-samples/bracket/main.kcl` or `src/lib/exampleKcl.ts` has been updated in this PR, please review and update the `src/routes/onboarding`, if needed.';
|
||||
const issue_number = context.payload.pull_request.number;
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
|
||||
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner,
|
||||
repo,
|
||||
@ -43,4 +44,4 @@ jobs:
|
||||
issue_number,
|
||||
body: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
13
.github/workflows/codemirror-lang-kcl.yml
vendored
13
.github/workflows/codemirror-lang-kcl.yml
vendored
@ -11,7 +11,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
yarn-unit-test:
|
||||
npm-unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -19,14 +19,11 @@ jobs:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- run: yarn install
|
||||
working-directory: packages/codemirror-lang-kcl
|
||||
- run: npm install
|
||||
|
||||
- run: yarn tsc
|
||||
working-directory: packages/codemirror-lang-kcl
|
||||
- run: npm run tsc --workspace=packages/codemirror-lang-kcl
|
||||
|
||||
- name: run unit tests
|
||||
run: yarn test
|
||||
working-directory: packages/codemirror-lang-kcl
|
||||
run: npm run test --workspace=packages/codemirror-lang-kcl
|
||||
|
87
.github/workflows/e2e-tests.yml
vendored
87
.github/workflows/e2e-tests.yml
vendored
@ -3,7 +3,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- all-e2e # this bypasses `fixme()` using `orRunWhenFullSuiteEnabled()`
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: 0 * * * * # hourly
|
||||
@ -97,11 +96,11 @@ jobs:
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
run: yarn
|
||||
run: npm install
|
||||
|
||||
- name: Download Wasm Cache
|
||||
id: download-wasm
|
||||
@ -154,7 +153,7 @@ jobs:
|
||||
- name: Build Wasm
|
||||
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||
shell: bash
|
||||
run: yarn build:wasm
|
||||
run: npm run build:wasm
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
@ -197,12 +196,12 @@ jobs:
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
id: deps-install
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
run: yarn
|
||||
run: npm install
|
||||
|
||||
- name: Cache Playwright Browsers
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
@ -210,27 +209,32 @@ jobs:
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright/
|
||||
key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
|
||||
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
run: npm run playwright install --with-deps
|
||||
|
||||
- name: build web
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
run: yarn tronb:vite:dev
|
||||
run: npm run tronb:vite:dev
|
||||
|
||||
- name: Run ubuntu/chrome snapshots
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
command: yarn test:snapshots
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
command: npm run test:snapshots
|
||||
timeout_minutes: 5
|
||||
max_attempts: 5
|
||||
env:
|
||||
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
|
||||
TAB_API_URL: ${{ secrets.TAB_API_URL }}
|
||||
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
||||
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
TARGET: web
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
|
||||
@ -278,23 +282,37 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# TODO: enable namespace-profile-windows-latest once available
|
||||
os:
|
||||
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
- namespace-profile-macos-8-cores
|
||||
- windows-latest-8-cores
|
||||
shardIndex: [1, 2, 3, 4]
|
||||
shardTotal: [4]
|
||||
# Disable macos and windows tests on hourly e2e tests since we only care
|
||||
# about server side changes.
|
||||
# Technique from https://github.com/joaomcteixeira/python-project-skeleton/pull/31/files
|
||||
isScheduled:
|
||||
- ${{ github.event_name == 'schedule' }}
|
||||
exclude:
|
||||
include:
|
||||
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
shardIndex: 1
|
||||
shardTotal: 8
|
||||
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
shardIndex: 2
|
||||
shardTotal: 8
|
||||
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
shardIndex: 3
|
||||
shardTotal: 8
|
||||
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
shardIndex: 4
|
||||
shardTotal: 8
|
||||
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
shardIndex: 5
|
||||
shardTotal: 8
|
||||
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
shardIndex: 6
|
||||
shardTotal: 8
|
||||
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
shardIndex: 7
|
||||
shardTotal: 8
|
||||
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||
shardIndex: 8
|
||||
shardTotal: 8
|
||||
- os: namespace-profile-macos-8-cores
|
||||
isScheduled: true
|
||||
shardIndex: 1
|
||||
shardTotal: 1
|
||||
- os: windows-latest-8-cores
|
||||
isScheduled: true
|
||||
# TODO: add ref here for main and latest release tag
|
||||
shardIndex: 1
|
||||
shardTotal: 1
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -316,12 +334,12 @@ jobs:
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
id: deps-install
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
run: yarn
|
||||
run: npm install
|
||||
|
||||
- name: Cache Playwright Browsers
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
@ -329,15 +347,15 @@ jobs:
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright/
|
||||
key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
|
||||
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
run: npm run playwright install --with-deps
|
||||
|
||||
- name: Build web
|
||||
if: needs.conditions.outputs.should-run == 'true'
|
||||
run: yarn tronb:vite:dev
|
||||
run: npm run tronb:vite:dev
|
||||
|
||||
- name: Start Vector
|
||||
if: ${{ needs.conditions.outputs.should-run == 'true' && !contains(matrix.os, 'windows') }}
|
||||
@ -365,6 +383,11 @@ jobs:
|
||||
env:
|
||||
FAIL_ON_CONSOLE_ERRORS: true
|
||||
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
TAB_API_URL: ${{ secrets.TAB_API_URL }}
|
||||
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
||||
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
TARGET: desktop
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ needs.conditions.outputs.should-run == 'true' && always() }}
|
||||
|
@ -21,10 +21,10 @@ jobs:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- run: yarn install
|
||||
- run: yarn generate:machine-api
|
||||
- run: yarn fmt
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
- run: npm run generate:machine-api
|
||||
- run: npm run fmt || true
|
||||
- name: check for changes
|
||||
id: git-check
|
||||
run: |
|
||||
|
30
.github/workflows/kcl-language-server.yml
vendored
30
.github/workflows/kcl-language-server.yml
vendored
@ -56,21 +56,19 @@ jobs:
|
||||
node-version-file: ".nvmrc"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
yarn install
|
||||
cd rust/kcl-language-server
|
||||
yarn install
|
||||
npm install
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
yarn build
|
||||
yarn test-compile
|
||||
npm run build
|
||||
npm run test-compile
|
||||
ls -la dist
|
||||
xvfb-run -a yarn test
|
||||
xvfb-run -a npm run test
|
||||
if: runner.os == 'Linux'
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
yarn test
|
||||
npm run test
|
||||
if: runner.os != 'Linux'
|
||||
build-release:
|
||||
strategy:
|
||||
@ -183,19 +181,20 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
# npm will symlink which will cause issues w tarballing later
|
||||
yarn install
|
||||
|
||||
- name: Package Extension (release)
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }}
|
||||
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }}
|
||||
|
||||
- name: Package Extension (nightly)
|
||||
if: startsWith(github.event.ref, 'refs/tags/') == false
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release
|
||||
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release
|
||||
|
||||
- name: remove server
|
||||
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
||||
@ -207,13 +206,13 @@ jobs:
|
||||
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/')
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package -o ../build/kcl-language-server-no-server.vsix
|
||||
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix
|
||||
|
||||
- name: Package Extension (no server, nightly)
|
||||
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/') == false
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package -o ../build/kcl-language-server-no-server.vsix --pre-release
|
||||
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix --pre-release
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@ -244,8 +243,8 @@ jobs:
|
||||
lld \
|
||||
musl-dev \
|
||||
nodejs \
|
||||
yarn \
|
||||
npm
|
||||
npm \
|
||||
yarn
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
@ -272,19 +271,20 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
# npm will symlink which will cause issues w tarballing later
|
||||
yarn install
|
||||
|
||||
- name: Package Extension (release)
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64
|
||||
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64
|
||||
|
||||
- name: Package Extension (release)
|
||||
if: startsWith(github.event.ref, 'refs/tags/') == false
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64 --pre-release
|
||||
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64 --pre-release
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
|
55
.github/workflows/nix.yml
vendored
Normal file
55
.github/workflows/nix.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
name: Test Nix Flake
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
nix-flake-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
|
||||
- name: nix flake check for all platforms
|
||||
run: |
|
||||
nix flake check --all-systems
|
||||
|
||||
nix-build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
|
||||
- name: nix build . for x86_64-linux
|
||||
run: nix build .
|
||||
|
||||
nix-build-macos:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
|
||||
- name: nix build . for x86_64-darwin
|
||||
run: nix build .
|
||||
|
6
.github/workflows/publish-apps-release.yml
vendored
6
.github/workflows/publish-apps-release.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Find tag workflow id
|
||||
id: tag_workflow_id
|
||||
@ -105,7 +105,7 @@ jobs:
|
||||
- name: Override release notes
|
||||
env:
|
||||
NOTES: ${{ github.event.release.body }}
|
||||
run: yarn files:set-notes
|
||||
run: npm run files:set-notes
|
||||
|
||||
- name: Authenticate to Google Cloud
|
||||
uses: 'google-github-actions/auth@v2.1.8'
|
||||
@ -126,7 +126,7 @@ jobs:
|
||||
destination: 'dl.kittycad.io/releases/modeling-app'
|
||||
|
||||
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
||||
run: yarn files:invalidate-bucket
|
||||
run: npm run files:invalidate-bucket
|
||||
|
||||
- name: Upload release files to Github
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
|
74
.github/workflows/static-analysis.yml
vendored
74
.github/workflows/static-analysis.yml
vendored
@ -16,18 +16,18 @@ permissions:
|
||||
actions: read
|
||||
|
||||
jobs:
|
||||
yarn-fmt-check:
|
||||
npm-fmt-check:
|
||||
runs-on: 'ubuntu-22.04'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- run: yarn install
|
||||
- run: yarn fmt-check
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
- run: npm run fmt:check
|
||||
|
||||
yarn-build-wasm:
|
||||
npm-build-wasm:
|
||||
# Build the wasm blob once on the fastest runner.
|
||||
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
|
||||
steps:
|
||||
@ -36,10 +36,10 @@ jobs:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
run: npm install
|
||||
|
||||
- name: Use correct Rust toolchain
|
||||
shell: bash
|
||||
@ -62,7 +62,7 @@ jobs:
|
||||
|
||||
- name: Build Wasm
|
||||
shell: bash
|
||||
run: yarn build:wasm
|
||||
run: npm run build:wasm
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@ -76,17 +76,17 @@ jobs:
|
||||
path: |
|
||||
rust/kcl-lib/bindings/*
|
||||
|
||||
yarn-tsc:
|
||||
npm-tsc:
|
||||
runs-on: ubuntu-latest
|
||||
needs: yarn-build-wasm
|
||||
needs: npm-build-wasm
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- run: yarn install
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@ -104,19 +104,19 @@ jobs:
|
||||
mkdir rust/kcl-lib/bindings
|
||||
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
||||
|
||||
- run: yarn tsc
|
||||
- run: npm run tsc
|
||||
|
||||
yarn-lint:
|
||||
npm-lint:
|
||||
runs-on: ubuntu-latest
|
||||
needs: yarn-build-wasm
|
||||
needs: npm-build-wasm
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- run: yarn install
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@ -134,19 +134,19 @@ jobs:
|
||||
mkdir rust/kcl-lib/bindings
|
||||
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
||||
|
||||
- run: yarn lint
|
||||
- run: npm run lint
|
||||
|
||||
yarn-circular-dependencies:
|
||||
npm-circular-dependencies:
|
||||
runs-on: ubuntu-latest
|
||||
needs: yarn-build-wasm
|
||||
needs: npm-build-wasm
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- run: yarn install
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@ -164,7 +164,7 @@ jobs:
|
||||
mkdir rust/kcl-lib/bindings
|
||||
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
||||
|
||||
- run: yarn circular-deps:diff
|
||||
- run: npm run circular-deps:diff
|
||||
|
||||
python-codespell:
|
||||
runs-on: ubuntu-22.04
|
||||
@ -179,18 +179,18 @@ jobs:
|
||||
- name: Run codespell
|
||||
run: codespell --config .codespellrc # Edit this file to tweak the typo list and other configuration.
|
||||
|
||||
yarn-unit-test-kcl-samples:
|
||||
npm-unit-test-kcl-samples:
|
||||
runs-on: ubuntu-latest
|
||||
needs: yarn-build-wasm
|
||||
needs: npm-build-wasm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- run: yarn install
|
||||
- run: npm install
|
||||
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||
with:
|
||||
tool: wasm-pack
|
||||
@ -211,31 +211,31 @@ jobs:
|
||||
mkdir rust/kcl-lib/bindings
|
||||
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
||||
|
||||
- run: yarn simpleserver:bg
|
||||
- run: npm run simpleserver:bg
|
||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||
|
||||
- name: Install Chromium Browser
|
||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||
run: yarn playwright install chromium --with-deps
|
||||
run: npm run playwright install chromium --with-deps
|
||||
|
||||
- name: run unit tests for kcl samples
|
||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||
run: yarn test:unit:kcl-samples
|
||||
run: npm run test:unit:kcl-samples
|
||||
env:
|
||||
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
|
||||
yarn-unit-test:
|
||||
npm-unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: yarn-build-wasm
|
||||
needs: npm-build-wasm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
cache: 'npm'
|
||||
|
||||
- run: yarn install
|
||||
- run: npm install
|
||||
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||
with:
|
||||
tool: wasm-pack
|
||||
@ -256,16 +256,16 @@ jobs:
|
||||
mkdir rust/kcl-lib/bindings
|
||||
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
||||
|
||||
- run: yarn simpleserver:bg
|
||||
- run: npm run simpleserver:bg
|
||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||
|
||||
- name: Install Chromium Browser
|
||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||
run: yarn playwright install chromium --with-deps
|
||||
run: npm run playwright install chromium --with-deps
|
||||
|
||||
- name: Run unit tests
|
||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||
run: xvfb-run -a yarn test:unit
|
||||
run: xvfb-run -a npm run test:unit
|
||||
env:
|
||||
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
|
||||
|
2
.github/workflows/tag-nightly.yml
vendored
2
.github/workflows/tag-nightly.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- run: yarn install
|
||||
- run: npm install
|
||||
|
||||
- name: Push tag
|
||||
run: |
|
||||
|
45
.github/workflows/update-e2e-branch.yml
vendored
45
.github/workflows/update-e2e-branch.yml
vendored
@ -1,45 +0,0 @@
|
||||
name: update-e2e-branch
|
||||
|
||||
# This is used to sync the `all-e2e` branch with the `main` branch for the
|
||||
# logic in the test utility `orRunWhenFullSuiteEnabled()` that allows all e2e
|
||||
# tests to run on a particular branch to analyze failures metrics in Axiom.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 * * * *' # runs every hour
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
update-branch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
||||
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
|
||||
owner: ${{ github.repository_owner }}
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- name: Sync with main
|
||||
run: |
|
||||
# Create the branch
|
||||
git checkout all-e2e || git checkout -b all-e2e
|
||||
|
||||
# Reset to main
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
|
||||
# Get a new SHA to prevent overwriting the commit status on main
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git commit --allow-empty --message="[all-e2e] $(git log --max-count=1 --pretty=%B)"
|
||||
|
||||
# Overwrite the branch
|
||||
git remote set-url origin https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository }}.git
|
||||
git push --force origin all-e2e
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -26,10 +26,12 @@ yarn-error.log*
|
||||
.idea
|
||||
.vscode
|
||||
.helix
|
||||
result
|
||||
|
||||
# rust
|
||||
rust/target
|
||||
rust/kcl-lib/bindings
|
||||
rust/kcl-language-server/server
|
||||
public/kcl_wasm_lib_bg.wasm
|
||||
rust/lcov.info
|
||||
rust/kcl-wasm-lib/pkg
|
||||
@ -82,3 +84,4 @@ dist
|
||||
venv
|
||||
|
||||
.vscode-test
|
||||
.biome/
|
||||
|
@ -5,6 +5,6 @@ command = "vscode-eslint-language-server"
|
||||
[[language]]
|
||||
name = "typescript"
|
||||
auto-format = true
|
||||
formatter = { command = "node_modules/.bin/prettier", args = ["--parser", "typescript"] }
|
||||
language-servers = [ { name = "eslint", only-features = [ "diagnostics" ] }, "typescript-language-server" ]
|
||||
formatter = { command = "./node_modules/@biomejs/biome/bin/biome", args = ["format", "--write", "--stdin-file-path=foo.ts"] }
|
||||
# language-servers = [ { name = "eslint", only-features = [ "diagnostics" ] }, "typescript-language-server" ]
|
||||
|
||||
|
1
.husky/pre-commit
Executable file
1
.husky/pre-commit
Executable file
@ -0,0 +1 @@
|
||||
npm run fmt
|
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
yarn fmt-check
|
432
CONTRIBUTING.md
Normal file
432
CONTRIBUTING.md
Normal file
@ -0,0 +1,432 @@
|
||||
# Contributor Guide
|
||||
|
||||
## Running a development build
|
||||
|
||||
Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=readme-ov-#installation).
|
||||
|
||||
On Windows, it's also recommended to [upgrade your PowerShell version](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.5#winget), we're using 7.
|
||||
|
||||
Then in the repo run the following to install and use the node version specified in `.nvmrc`. You might need to specify your processor architecture with `--arch arm64` or `--arch x64` if it's not autodetected.
|
||||
|
||||
```
|
||||
fnm install --corepack-enabled
|
||||
fnm use
|
||||
```
|
||||
|
||||
Install the NPM dependencies with:
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
This project uses a lot of Rust compiled to [WASM](https://webassembly.org/) within it. We have package scripts to run rustup, see `package.json` for reference:
|
||||
|
||||
```
|
||||
# macOS/Linux
|
||||
npm run install:rust
|
||||
npm run install:wasm-pack:sh
|
||||
|
||||
# Windows
|
||||
npm run install:rust:windows
|
||||
npm run install:wasm-pack:cargo
|
||||
```
|
||||
|
||||
Then to build the WASM layer, run:
|
||||
|
||||
```
|
||||
# macOS/Linux
|
||||
npm run build:wasm
|
||||
|
||||
# Windows
|
||||
npm run build:wasm:windows
|
||||
```
|
||||
|
||||
Or if you have the `gh` cli installed and want to download the latest main wasm bundle. Note that on Windows, you need to associate .ps1 files with PowerShell, which can be done via the right click menu, selecting `C:\Program Files\PowerShell\7\pwsh.exe`, and you can install tools like `gh` via `npm run install:tools:windows`.
|
||||
|
||||
```
|
||||
# macOS/Linux
|
||||
npm run fetch:wasm
|
||||
|
||||
# Windows
|
||||
npm run fetch:wasm:windows
|
||||
```
|
||||
|
||||
That will build the WASM binary and put in the `public` dir (though gitignored).
|
||||
|
||||
Finally, to run the web app only, run:
|
||||
|
||||
```
|
||||
npm start
|
||||
```
|
||||
|
||||
If you're not a Zoo employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development.local` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens of course, then navigate to `localhost:3000` again. Note that navigating to `localhost:3000/signin` removes your token so you will need to set the token again.
|
||||
|
||||
### Development environment variables
|
||||
|
||||
The Copilot LSP plugin in the editor requires a Zoo API token to run. In production, we authenticate this with a token via cookie in the browser and device auth token in the desktop environment, but this token is inaccessible in the dev browser version because the cookie is considered "cross-site" (from `localhost` to `dev.zoo.dev`). There is an optional environment variable called `VITE_KC_DEV_TOKEN` that you can populate with a dev token in a `.env.development.local` file to not check it into Git, which will use that token instead of other methods for the LSP service.
|
||||
|
||||
### Developing in Chrome
|
||||
|
||||
Chrome is in the process of rolling out a new default which
|
||||
[blocks Third-Party Cookies](https://developer.chrome.com/en/docs/privacy-sandbox/third-party-cookie-phase-out/).
|
||||
If you're having trouble logging into the `modeling-app`, you may need to
|
||||
enable third-party cookies. You can enable third-party cookies by clicking on
|
||||
the eye with a slash through it in the URL bar, and clicking on "Enable
|
||||
Third-Party Cookies".
|
||||
|
||||
## Desktop
|
||||
|
||||
To spin up the desktop app, `npm install` and `npm run build:wasm` need to have been done before hand then:
|
||||
|
||||
```
|
||||
npm run tron:start
|
||||
```
|
||||
|
||||
This will start the application and hot-reload on changes.
|
||||
|
||||
Devtools can be opened with the usual Command-Option-I (macOS) or Ctrl-Shift-I (Linux and Windows).
|
||||
|
||||
To package the app for your platform with electron-builder, run `npm run tronb:package:dev` (or `npm run tronb:package:prod` to point to the .env.production variables).
|
||||
|
||||
## Checking out commits / Bisecting
|
||||
|
||||
Which commands from setup are one off vs. need to be run every time?
|
||||
|
||||
The following will need to be run when checking out a new commit and guarantees the build is not stale:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run build:wasm
|
||||
npm start # or npm run build:local && npm run serve for slower but more production-like build
|
||||
```
|
||||
|
||||
## Before submitting a PR
|
||||
|
||||
Before you submit a contribution PR to this repo, please ensure that:
|
||||
|
||||
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
|
||||
- You have separated out refactoring commits from feature commits as much as possible
|
||||
- You have run all of the following commands locally:
|
||||
- `npm run fmt`
|
||||
- `npm run tsc`
|
||||
- `npm run test`
|
||||
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
|
||||
|
||||
## Release a new version
|
||||
|
||||
#### 1. Create a 'Cut release $VERSION' issue
|
||||
|
||||
It will be used to document changelog discussions and release testing.
|
||||
|
||||
https://github.com/KittyCAD/modeling-app/issues/new
|
||||
|
||||
#### 2. Push a new tag
|
||||
|
||||
Create a new tag and push it to the repo. The `semantic-release.sh` script will automatically bump the minor part, which we use the most. For instance going from `v0.27.0` to `v0.28.0`.
|
||||
|
||||
```
|
||||
VERSION=$(./scripts/semantic-release.sh)
|
||||
git tag $VERSION
|
||||
git push origin --tags
|
||||
```
|
||||
|
||||
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
|
||||
|
||||
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
|
||||
|
||||
#### 3. Manually test artifacts
|
||||
|
||||
##### Release builds
|
||||
|
||||
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in 2.).
|
||||
|
||||
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
|
||||
|
||||
##### Updater-test builds
|
||||
|
||||
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
|
||||
|
||||
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
|
||||
|
||||
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
|
||||
|
||||
```
|
||||
# Windows (PowerShell)
|
||||
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe'
|
||||
|
||||
# macOS
|
||||
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
|
||||
|
||||
# Linux
|
||||
./Zoo Design Studio-{version}-{arch}-linux.AppImage
|
||||
```
|
||||
|
||||
#### 4. Publish the release
|
||||
|
||||
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the _Release title_ field as well.
|
||||
|
||||
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
|
||||
|
||||
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
|
||||
|
||||
#### 5. Close the issue
|
||||
|
||||
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
|
||||
|
||||
## Fuzzing the parser
|
||||
|
||||
Make sure you install cargo fuzz:
|
||||
|
||||
```bash
|
||||
$ cargo install cargo-fuzz
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cd rust/kcl-lib
|
||||
|
||||
# list the fuzz targets
|
||||
$ cargo fuzz list
|
||||
|
||||
# run the parser fuzzer
|
||||
$ cargo +nightly fuzz run parser
|
||||
```
|
||||
|
||||
For more information on fuzzing you can check out
|
||||
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
|
||||
|
||||
## Tests
|
||||
|
||||
### Playwright tests
|
||||
|
||||
You will need a `./e2e/playwright/playwright-secrets.env` file:
|
||||
|
||||
```bash
|
||||
$ touch ./e2e/playwright/playwright-secrets.env
|
||||
$ cat ./e2e/playwright/playwright-secrets.env
|
||||
token=<dev.zoo.dev/account/api-tokens>
|
||||
snapshottoken=<zoo.dev/account/api-tokens>
|
||||
```
|
||||
or use `export` to set the environment variables `token` and `snapshottoken`.
|
||||
|
||||
#### Snapshot tests (Google Chrome on Ubuntu only)
|
||||
|
||||
Only Ubunu and Google Chrome is supported for the set of tests evaluating screenshot snapshots.
|
||||
If you don't run Ubuntu locally or in a VM, you may use a GitHub Codespace.
|
||||
```
|
||||
npm run playwright -- install chrome
|
||||
npm run test:snapshots
|
||||
```
|
||||
You may use `-- --update-snapshots` as needed.
|
||||
|
||||
#### Electron flow tests (Chromium on Ubuntu, macOS, Windows)
|
||||
|
||||
```
|
||||
npm run playwright -- install chromium
|
||||
npm run test:playwright:electron:local
|
||||
```
|
||||
You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file.
|
||||
|
||||
#### Debugger
|
||||
|
||||
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.
|
||||
With the extension you can set a breakpoint after `waitForDefaultPlanesVisibilityChange` in order to skip app loading, then the vscode debugger's "step over" is much better for being able to stay at the right level of abstraction as you debug the code.
|
||||
|
||||
If you want to limit to a single browser use `--project="webkit"` or `firefox`, `Google Chrome`
|
||||
Or comment out browsers in `playwright.config.ts`.
|
||||
|
||||
note chromium has encoder compat issues which is why were testing against the branded 'Google Chrome'
|
||||
|
||||
You may consider using the VSCode extension, it's useful for running individual threads, but some some reason the "record a test" is locked to chromium with we can't use. A work around is to us the CI `npm run playwright codegen -b wk --load-storage ./store localhost:3000`
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
|
||||
Where `./store` should look like this
|
||||
|
||||
</summary>
|
||||
|
||||
```JSON
|
||||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:3000",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "store",
|
||||
"value": "{\"state\":{\"openPanes\":[\"code\"]},\"version\":0}"
|
||||
},
|
||||
{
|
||||
"name": "persistCode",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"name": "TOKEN_PERSIST_KEY",
|
||||
"value": "your-token"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
However because much of our tests involve clicking in the stream at specific locations, it's code-gen looks `await page.locator('video').click();` when really we need to use a pixel coord, so I think it's of limited use.
|
||||
|
||||
### Unit and component tests
|
||||
|
||||
If you already haven't, run the following:
|
||||
|
||||
```
|
||||
npm
|
||||
npm run build:wasm
|
||||
npm start
|
||||
```
|
||||
|
||||
and finally:
|
||||
|
||||
```
|
||||
npm run test:unit
|
||||
```
|
||||
|
||||
For individual testing:
|
||||
|
||||
```
|
||||
npm run test abstractSyntaxTree -t "unexpected closed curly brace" --silent=false
|
||||
```
|
||||
|
||||
Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testing Library E2E](https://testing-library.com/docs/react-testing-library/intro) tests, in interactive mode by default.
|
||||
|
||||
### Rust tests
|
||||
|
||||
**Dependencies**
|
||||
|
||||
- `KITTYCAD_API_TOKEN`
|
||||
- `cargo-nextest`
|
||||
- `just`
|
||||
|
||||
#### Setting KITTYCAD_API_TOKEN
|
||||
|
||||
Use the production zoo.dev token, set this environment variable before running the tests
|
||||
|
||||
#### Installing cargonextest
|
||||
|
||||
```
|
||||
cd rust
|
||||
cargo search cargo-nextest
|
||||
cargo install cargo-nextest
|
||||
```
|
||||
|
||||
#### just
|
||||
|
||||
install [`just`](https://github.com/casey/just?tab=readme-ov-file#pre-built-binaries)
|
||||
|
||||
#### Running the tests
|
||||
|
||||
```bash
|
||||
# With just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
# Make sure you installed just
|
||||
cd rust
|
||||
just test
|
||||
```
|
||||
|
||||
```bash
|
||||
# Without just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
cd rust
|
||||
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
|
||||
```
|
||||
|
||||
Where `XXX` is an API token from the production engine (NOT the dev environment).
|
||||
|
||||
We recommend using [nextest](https://nexte.st/) to run the Rust tests (its faster and is used in CI). Once installed, run the tests using
|
||||
|
||||
```
|
||||
cd rust
|
||||
KITTYCAD_API_TOKEN=XXX cargo run nextest
|
||||
```
|
||||
|
||||
### Mapping CI CD jobs to local commands
|
||||
|
||||
When you see the CI CD fail on jobs you may wonder three things
|
||||
|
||||
- Do I have a bug in my code?
|
||||
- Is the test flaky?
|
||||
- Is there a bug in `main`?
|
||||
|
||||
To answer these questions the following commands will give you confidence to locate the issue.
|
||||
|
||||
#### Static Analysis
|
||||
|
||||
Part of the CI CD pipeline performs static analysis on the code. Use the following commands to mimic the CI CD jobs.
|
||||
|
||||
The following set of commands should get us closer to one and done commands to instantly retest issues.
|
||||
|
||||
```
|
||||
npm run test-setup
|
||||
```
|
||||
|
||||
> Gotcha, are packages up to date and is the wasm built?
|
||||
|
||||
```
|
||||
npm run tsc
|
||||
npm run fmt:check
|
||||
npm run lint
|
||||
npm run test:unit:local
|
||||
```
|
||||
|
||||
> Gotcha: Our unit tests have integration tests in them. You need to run a localhost server to run the unit tests.
|
||||
|
||||
#### E2E Tests
|
||||
|
||||
**Playwright Electron**
|
||||
|
||||
These E2E tests run in electron. There are tests that are skipped if they are ran in a windows, linux, or macos environment. We can use playwright tags to implement test skipping.
|
||||
|
||||
```
|
||||
npm run test:playwright:electron:local
|
||||
npm run test:playwright:electron:windows:local
|
||||
npm run test:playwright:electron:macos:local
|
||||
npm run test:playwright:electron:ubuntu:local
|
||||
```
|
||||
|
||||
> Why does it say local? The CI CD commands that run in the pipeline cannot be ran locally. A single command will not properly setup the testing environment locally.
|
||||
|
||||
#### Some notes on CI
|
||||
|
||||
The tests are broken into snapshot tests and non-snapshot tests, and they run in that order, they automatically commit new snap shots, so if you see an image commit check it was an intended change. If we have non-determinism in the snapshots such that they are always committing new images, hopefully this annoyance makes us fix them asap, if you notice this happening let Kurt know. But for the odd occasion `git reset --hard HEAD~ && git push -f` is your friend.
|
||||
|
||||
How to interpret failing playwright tests?
|
||||
If your tests fail, click through to the action and see that the tests failed on a line that includes `await page.getByTestId('loading').waitFor({ state: 'detached' })`, this means the test fail because the stream never started. It's you choice if you want to re-run the test, or ignore the failure.
|
||||
|
||||
We run on ubuntu and macos, because safari doesn't work on linux because of the dreaded "no RTCPeerConnection variable" error. But linux runs first and then macos for the same reason that we limit the number of parallel tests to 1 because we limit stream connections per user, so tests would start failing we if let them run together.
|
||||
|
||||
If something fails on CI you can download the artifact, unzip it and then open `playwright-report/data/<UUID>.zip` with https://trace.playwright.dev/ to see what happened.
|
||||
|
||||
#### Getting started writing a playwright test in our app
|
||||
|
||||
Besides following the instructions above and using the playwright docs, our app is weird because of the whole stream thing, which means our testing is weird. Because we've just figured out this stuff and therefore docs might go stale quick here's a 15min vid/tutorial
|
||||
|
||||
https://github.com/KittyCAD/modeling-app/assets/29681384/6f5e8e85-1003-4fd9-be7f-f36ce833942d
|
||||
|
||||
<details>
|
||||
|
||||
<summary>
|
||||
PS: for the debug panel, the following JSON is useful for snapping the camera
|
||||
</summary>
|
||||
|
||||
```JSON
|
||||
{"type":"modeling_cmd_req","cmd_id":"054e5472-e5e9-4071-92d7-1ce3bac61956","cmd":{"type":"default_camera_look_at","center":{"x":15,"y":0,"z":0},"up":{"x":0,"y":0,"z":1},"vantage":{"x":30,"y":30,"z":30}}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Logging
|
||||
|
||||
To display logging (to the terminal or console) set `ZOO_LOG=1`. This will log some warnings and simple performance metrics. To view these in test runs, use `-- --nocapture`.
|
||||
|
||||
To enable memory metrics, build with `--features dhat-heap`.
|
55
Makefile
55
Makefile
@ -15,33 +15,28 @@ ifdef WINDOWS
|
||||
CARGO ?= $(USERPROFILE)/.cargo/bin/cargo.exe
|
||||
WASM_PACK ?= $(USERPROFILE)/.cargo/bin/wasm-pack.exe
|
||||
else
|
||||
CARGO ?= ~/.cargo/bin/cargo
|
||||
WASM_PACK ?= ~/.cargo/bin/wasm-pack
|
||||
endif
|
||||
CARGO ?= $(shell which cargo || echo ~/.cargo/bin/cargo)
|
||||
WASM_PACK ?= $(shell which wasm-pack || echo ~/.cargo/bin/wasm-pack)
|
||||
endif
|
||||
|
||||
.PHONY: install
|
||||
install: node_modules/.yarn-integrity $(CARGO) $(WASM_PACK) ## Install dependencies
|
||||
install: node_modules/.package-lock.json $(CARGO) $(WASM_PACK) ## Install dependencies
|
||||
|
||||
node_modules/.yarn-integrity: package.json yarn.lock
|
||||
yarn install
|
||||
ifdef POWERSHELL
|
||||
@ type nul > $@
|
||||
else
|
||||
@ touch $@
|
||||
endif
|
||||
node_modules/.package-lock.json: package.json package-lock.json
|
||||
npm install
|
||||
|
||||
$(CARGO):
|
||||
ifdef WINDOWS
|
||||
yarn install:rust:windows
|
||||
npm run install:rust:windows
|
||||
else
|
||||
yarn install:rust
|
||||
npm run install:rust
|
||||
endif
|
||||
|
||||
$(WASM_PACK):
|
||||
ifdef WINDOWS
|
||||
yarn install:wasm-pack:cargo
|
||||
npm run install:wasm-pack:cargo
|
||||
else
|
||||
yarn install:wasm-pack:sh
|
||||
npm run install:wasm-pack:sh
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
@ -65,16 +60,16 @@ build-desktop: install public/kcl_wasm_lib_bg.wasm .vite/build/main.js
|
||||
|
||||
public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES) $(RUST_SOURCES)
|
||||
ifdef WINDOWS
|
||||
yarn build:wasm:dev:windows
|
||||
npm run build:wasm:dev:windows
|
||||
else
|
||||
yarn build:wasm:dev
|
||||
npm run build:wasm:dev
|
||||
endif
|
||||
|
||||
build/index.html: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
|
||||
yarn build:local
|
||||
npm run build:local
|
||||
|
||||
.vite/build/main.js: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
|
||||
yarn tronb:vite:dev
|
||||
npm run tronb:vite:dev
|
||||
|
||||
###############################################################################
|
||||
# CHECK
|
||||
@ -84,12 +79,12 @@ check: format lint
|
||||
|
||||
.PHONY: format
|
||||
format: install ## Format the code
|
||||
yarn fmt
|
||||
npm run fmt
|
||||
|
||||
.PHONY: lint
|
||||
lint: install ## Lint the code
|
||||
yarn tsc
|
||||
yarn lint
|
||||
npm run tsc
|
||||
npm run lint
|
||||
|
||||
###############################################################################
|
||||
# RUN
|
||||
@ -101,11 +96,11 @@ run: run-$(TARGET)
|
||||
|
||||
.PHONY: run-web
|
||||
run-web: install build-web ## Start the web app
|
||||
yarn start
|
||||
npm run start
|
||||
|
||||
.PHONY: run-desktop
|
||||
run-desktop: install build-desktop ## Start the desktop app
|
||||
yarn tron:start
|
||||
npm run tron:start
|
||||
|
||||
###############################################################################
|
||||
# TEST
|
||||
@ -120,7 +115,7 @@ test: test-unit test-e2e
|
||||
.PHONY: test-unit
|
||||
test-unit: install ## Run the unit tests
|
||||
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
|
||||
yarn test:unit
|
||||
npm run test:unit
|
||||
|
||||
.PHONY: test-e2e
|
||||
test-e2e: test-e2e-$(TARGET)
|
||||
@ -129,17 +124,17 @@ test-e2e: test-e2e-$(TARGET)
|
||||
test-e2e-web: install build-web ## Run the web e2e tests
|
||||
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
|
||||
ifdef E2E_GREP
|
||||
yarn chrome:test --headed --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
|
||||
npm run chrome:test -- --headed --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
|
||||
else
|
||||
yarn chrome:test --headed --workers='100%'
|
||||
npm run chrome:test -- --headed --workers='100%'
|
||||
endif
|
||||
|
||||
.PHONY: test-e2e-desktop
|
||||
test-e2e-desktop: install build-desktop ## Run the desktop e2e tests
|
||||
ifdef E2E_GREP
|
||||
yarn test:playwright:electron --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
|
||||
npm run test:playwright:electron -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
|
||||
else
|
||||
yarn test:playwright:electron --workers='100%'
|
||||
npm run test:playwright:electron -- --workers='100%'
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
@ -174,5 +169,5 @@ endif
|
||||
# It should work for you other Linux users.
|
||||
lee-electron-test:
|
||||
Xephyr -br -ac -noreset -screen 1200x500 :2 &
|
||||
DISPLAY=:2 NODE_ENV=development PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn tron:test -g "when using the file tree"
|
||||
DISPLAY=:2 NODE_ENV=development PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ npm run tron:test -g "when using the file tree"
|
||||
killall Xephyr
|
||||
|
473
README.md
473
README.md
@ -1,8 +1,8 @@
|
||||

|
||||
|
||||
## Zoo Design Studio
|
||||
# Zoo Design Studio
|
||||
|
||||
download at [zoo.dev/modeling-app/download](https://zoo.dev/modeling-app/download)
|
||||
[zoo.dev/modeling-app](https://zoo.dev/modeling-app)
|
||||
|
||||
A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev).
|
||||
|
||||
@ -23,7 +23,7 @@ Design Studio is a _hybrid_ user interface for CAD modeling. You can point-and-c
|
||||
|
||||
The 3D view in Design Studio is just a video stream from our hosted geometry engine. The app sends new modeling commands to the engine via WebSockets, which returns back video frames of the view within the engine.
|
||||
|
||||
## Tools
|
||||
## Technology
|
||||
|
||||
- UI
|
||||
- [React](https://react.dev/)
|
||||
@ -38,471 +38,16 @@ The 3D view in Design Studio is just a video stream from our hosted geometry eng
|
||||
- Modeling
|
||||
- [KittyCAD TypeScript client](https://github.com/KittyCAD/kittycad.ts)
|
||||
|
||||
[Original demo video](https://drive.google.com/file/d/183_wjqGdzZ8EEZXSqZ3eDcJocYPCyOdC/view?pli=1)
|
||||
## Get Started
|
||||
|
||||
[Original demo slides](https://github.com/user-attachments/files/19010536/demo.pdf)
|
||||
We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
|
||||
|
||||
## Get started
|
||||
If you'd like to try out upcoming changes sooner, you can also download those from our [nightly releases](https://zoo.dev/modeling-app/download/nightly) page.
|
||||
|
||||
We recommend downloading the latest application binary from [our Releases page](https://github.com/KittyCAD/modeling-app/releases). If you don't see your platform or architecture supported there, please file an issue.
|
||||
## Developing
|
||||
|
||||
## Running a development build
|
||||
|
||||
Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=readme-ov-#installation).
|
||||
|
||||
On Windows, it's also recommended to [upgrade your PowerShell version](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.5#winget), we're using 7.
|
||||
|
||||
Then in the repo run the following to install and use the node version specified in `.nvmrc`. You might need to specify your processor architecture with `--arch arm64` or `--arch x64` if it's not autodetected.
|
||||
|
||||
```
|
||||
fnm install --corepack-enabled
|
||||
fnm use
|
||||
```
|
||||
|
||||
Install the NPM dependencies with:
|
||||
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
This project uses a lot of Rust compiled to [WASM](https://webassembly.org/) within it. We have package scripts to run rustup, see `package.json` for reference:
|
||||
|
||||
```
|
||||
# macOS/Linux
|
||||
yarn install:rust
|
||||
yarn install:wasm-pack:sh
|
||||
|
||||
# Windows
|
||||
yarn install:rust:windows
|
||||
yarn install:wasm-pack:cargo
|
||||
```
|
||||
|
||||
Then to build the WASM layer, run:
|
||||
|
||||
```
|
||||
# macOS/Linux
|
||||
yarn build:wasm
|
||||
|
||||
# Windows
|
||||
yarn build:wasm:windows
|
||||
```
|
||||
|
||||
Or if you have the `gh` cli installed and want to download the latest main wasm bundle. Note that on Windows, you need to associate .ps1 files with PowerShell, which can be done via the right click menu, selecting `C:\Program Files\PowerShell\7\pwsh.exe`, and you can install tools like `gh` via `yarn install:tools:windows`.
|
||||
|
||||
```
|
||||
# macOS/Linux
|
||||
yarn fetch:wasm
|
||||
|
||||
# Windows
|
||||
yarn fetch:wasm:windows
|
||||
```
|
||||
|
||||
That will build the WASM binary and put in the `public` dir (though gitignored).
|
||||
|
||||
Finally, to run the web app only, run:
|
||||
|
||||
```
|
||||
yarn start
|
||||
```
|
||||
|
||||
If you're not a Zoo employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development.local` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens of course, then navigate to `localhost:3000` again. Note that navigating to `localhost:3000/signin` removes your token so you will need to set the token again.
|
||||
|
||||
### Development environment variables
|
||||
|
||||
The Copilot LSP plugin in the editor requires a Zoo API token to run. In production, we authenticate this with a token via cookie in the browser and device auth token in the desktop environment, but this token is inaccessible in the dev browser version because the cookie is considered "cross-site" (from `localhost` to `dev.zoo.dev`). There is an optional environment variable called `VITE_KC_DEV_TOKEN` that you can populate with a dev token in a `.env.development.local` file to not check it into Git, which will use that token instead of other methods for the LSP service.
|
||||
|
||||
### Developing in Chrome
|
||||
|
||||
Chrome is in the process of rolling out a new default which
|
||||
[blocks Third-Party Cookies](https://developer.chrome.com/en/docs/privacy-sandbox/third-party-cookie-phase-out/).
|
||||
If you're having trouble logging into the `modeling-app`, you may need to
|
||||
enable third-party cookies. You can enable third-party cookies by clicking on
|
||||
the eye with a slash through it in the URL bar, and clicking on "Enable
|
||||
Third-Party Cookies".
|
||||
|
||||
## Desktop
|
||||
|
||||
To spin up the desktop app, `yarn install` and `yarn build:wasm` need to have been done before hand then:
|
||||
|
||||
```
|
||||
yarn tron:start
|
||||
```
|
||||
|
||||
This will start the application and hot-reload on changes.
|
||||
|
||||
Devtools can be opened with the usual Command-Option-I (macOS) or Ctrl-Shift-I (Linux and Windows).
|
||||
|
||||
To package the app for your platform with electron-builder, run `yarn tronb:package:dev` (or `yarn tronb:package:prod` to point to the .env.production variables).
|
||||
|
||||
## Checking out commits / Bisecting
|
||||
|
||||
Which commands from setup are one off vs. need to be run every time?
|
||||
|
||||
The following will need to be run when checking out a new commit and guarantees the build is not stale:
|
||||
|
||||
```bash
|
||||
yarn install
|
||||
yarn build:wasm
|
||||
yarn start # or yarn build:local && yarn serve for slower but more production-like build
|
||||
```
|
||||
|
||||
## Before submitting a PR
|
||||
|
||||
Before you submit a contribution PR to this repo, please ensure that:
|
||||
|
||||
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
|
||||
- You have separated out refactoring commits from feature commits as much as possible
|
||||
- You have run all of the following commands locally:
|
||||
- `yarn fmt`
|
||||
- `yarn tsc`
|
||||
- `yarn test`
|
||||
- Here they are all together: `yarn fmt && yarn tsc && yarn test`
|
||||
|
||||
## Release a new version
|
||||
|
||||
#### 1. Create a 'Cut release $VERSION' issue
|
||||
|
||||
It will be used to document changelog discussions and release testing.
|
||||
|
||||
https://github.com/KittyCAD/modeling-app/issues/new
|
||||
|
||||
#### 2. Push a new tag
|
||||
|
||||
Create a new tag and push it to the repo. The `semantic-release.sh` script will automatically bump the minor part, which we use the most. For instance going from `v0.27.0` to `v0.28.0`.
|
||||
|
||||
```
|
||||
VERSION=$(./scripts/semantic-release.sh)
|
||||
git tag $VERSION
|
||||
git push origin --tags
|
||||
```
|
||||
|
||||
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
|
||||
|
||||
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
|
||||
|
||||
#### 3. Manually test artifacts
|
||||
|
||||
##### Release builds
|
||||
|
||||
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in 2.).
|
||||
|
||||
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
|
||||
|
||||
##### Updater-test builds
|
||||
|
||||
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
|
||||
|
||||
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
|
||||
|
||||
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
|
||||
|
||||
```
|
||||
# Windows (PowerShell)
|
||||
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe'
|
||||
|
||||
# macOS
|
||||
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
|
||||
|
||||
# Linux
|
||||
./Zoo Design Studio-{version}-{arch}-linux.AppImage
|
||||
```
|
||||
|
||||
#### 4. Publish the release
|
||||
|
||||
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the _Release title_ field as well.
|
||||
|
||||
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
|
||||
|
||||
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
|
||||
|
||||
#### 5. Close the issue
|
||||
|
||||
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
|
||||
|
||||
## Fuzzing the parser
|
||||
|
||||
Make sure you install cargo fuzz:
|
||||
|
||||
```bash
|
||||
$ cargo install cargo-fuzz
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cd rust/kcl-lib
|
||||
|
||||
# list the fuzz targets
|
||||
$ cargo fuzz list
|
||||
|
||||
# run the parser fuzzer
|
||||
$ cargo +nightly fuzz run parser
|
||||
```
|
||||
|
||||
For more information on fuzzing you can check out
|
||||
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
|
||||
|
||||
## Tests
|
||||
|
||||
### Playwright tests
|
||||
|
||||
You will need a `./e2e/playwright/playwright-secrets.env` file:
|
||||
|
||||
```bash
|
||||
$ touch ./e2e/playwright/playwright-secrets.env
|
||||
$ cat ./e2e/playwright/playwright-secrets.env
|
||||
token=<dev.zoo.dev/account/api-tokens>
|
||||
snapshottoken=<your-snapshot-token>
|
||||
```
|
||||
|
||||
For a portable way to run Playwright you'll need Docker.
|
||||
|
||||
#### Generic example
|
||||
|
||||
After that, open a terminal and run:
|
||||
|
||||
```bash
|
||||
docker run --network host --rm --init -it playwright/chrome:playwright-x.xx.x
|
||||
```
|
||||
|
||||
and in another terminal, run:
|
||||
|
||||
```bash
|
||||
PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn playwright test --project="Google Chrome" <test suite>
|
||||
```
|
||||
|
||||
#### Specific example
|
||||
|
||||
open a terminal and run:
|
||||
|
||||
```bash
|
||||
docker run --network host --rm --init -it playwright/chrome:playwright-1.46.0
|
||||
```
|
||||
|
||||
and in another terminal, run:
|
||||
|
||||
```bash
|
||||
PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn playwright test --project="Google Chrome" e2e/playwright/command-bar-tests.spec.ts
|
||||
```
|
||||
|
||||
run a specific test change the test from `test('...` to `test.only('...`
|
||||
(note if you commit this, the tests will instantly fail without running any of the tests)
|
||||
|
||||
**Gotcha**: running the docker container with a mismatched image against your `./node_modules/playwright` will cause a failure. Make sure the versions are matched and up to date.
|
||||
|
||||
run headed
|
||||
|
||||
```
|
||||
yarn playwright test --headed
|
||||
```
|
||||
|
||||
run with step through debugger
|
||||
|
||||
```
|
||||
PWDEBUG=1 yarn playwright test
|
||||
```
|
||||
|
||||
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.
|
||||
With the extension you can set a breakpoint after `waitForDefaultPlanesVisibilityChange` in order to skip app loading, then the vscode debugger's "step over" is much better for being able to stay at the right level of abstraction as you debug the code.
|
||||
|
||||
If you want to limit to a single browser use `--project="webkit"` or `firefox`, `Google Chrome`
|
||||
Or comment out browsers in `playwright.config.ts`.
|
||||
|
||||
note chromium has encoder compat issues which is why were testing against the branded 'Google Chrome'
|
||||
|
||||
You may consider using the VSCode extension, it's useful for running individual threads, but some some reason the "record a test" is locked to chromium with we can't use. A work around is to us the CI `yarn playwright codegen -b wk --load-storage ./store localhost:3000`
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
|
||||
Where `./store` should look like this
|
||||
|
||||
</summary>
|
||||
|
||||
```JSON
|
||||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:3000",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "store",
|
||||
"value": "{\"state\":{\"openPanes\":[\"code\"]},\"version\":0}"
|
||||
},
|
||||
{
|
||||
"name": "persistCode",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"name": "TOKEN_PERSIST_KEY",
|
||||
"value": "your-token"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
However because much of our tests involve clicking in the stream at specific locations, it's code-gen looks `await page.locator('video').click();` when really we need to use a pixel coord, so I think it's of limited use.
|
||||
|
||||
### Unit and component tests
|
||||
|
||||
If you already haven't, run the following:
|
||||
|
||||
```
|
||||
yarn
|
||||
yarn build:wasm
|
||||
yarn start
|
||||
```
|
||||
|
||||
and finally:
|
||||
|
||||
```
|
||||
yarn test:unit
|
||||
```
|
||||
|
||||
For individual testing:
|
||||
|
||||
```
|
||||
yarn test abstractSyntaxTree -t "unexpected closed curly brace" --silent=false
|
||||
```
|
||||
|
||||
Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testing Library E2E](https://testing-library.com/docs/react-testing-library/intro) tests, in interactive mode by default.
|
||||
|
||||
### Rust tests
|
||||
|
||||
**Dependencies**
|
||||
|
||||
- `KITTYCAD_API_TOKEN`
|
||||
- `cargo-nextest`
|
||||
- `just`
|
||||
|
||||
#### Setting KITTYCAD_API_TOKEN
|
||||
|
||||
Use the production zoo.dev token, set this environment variable before running the tests
|
||||
|
||||
#### Installing cargonextest
|
||||
|
||||
```
|
||||
cd rust
|
||||
cargo search cargo-nextest
|
||||
cargo install cargo-nextest
|
||||
```
|
||||
|
||||
#### just
|
||||
|
||||
install [`just`](https://github.com/casey/just?tab=readme-ov-file#pre-built-binaries)
|
||||
|
||||
#### Running the tests
|
||||
|
||||
```bash
|
||||
# With just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
# Make sure you installed just
|
||||
cd rust
|
||||
just test
|
||||
```
|
||||
|
||||
```bash
|
||||
# Without just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
cd rust
|
||||
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
|
||||
```
|
||||
|
||||
Where `XXX` is an API token from the production engine (NOT the dev environment).
|
||||
|
||||
We recommend using [nextest](https://nexte.st/) to run the Rust tests (its faster and is used in CI). Once installed, run the tests using
|
||||
|
||||
```
|
||||
cd rust
|
||||
KITTYCAD_API_TOKEN=XXX cargo run nextest
|
||||
```
|
||||
|
||||
### Mapping CI CD jobs to local commands
|
||||
|
||||
When you see the CI CD fail on jobs you may wonder three things
|
||||
|
||||
- Do I have a bug in my code?
|
||||
- Is the test flaky?
|
||||
- Is there a bug in `main`?
|
||||
|
||||
To answer these questions the following commands will give you confidence to locate the issue.
|
||||
|
||||
#### Static Analysis
|
||||
|
||||
Part of the CI CD pipeline performs static analysis on the code. Use the following commands to mimic the CI CD jobs.
|
||||
|
||||
The following set of commands should get us closer to one and done commands to instantly retest issues.
|
||||
|
||||
```
|
||||
yarn test-setup
|
||||
```
|
||||
|
||||
> Gotcha, are packages up to date and is the wasm built?
|
||||
|
||||
```
|
||||
yarn tsc
|
||||
yarn fmt-check
|
||||
yarn lint
|
||||
yarn test:unit:local
|
||||
```
|
||||
|
||||
> Gotcha: Our unit tests have integration tests in them. You need to run a localhost server to run the unit tests.
|
||||
|
||||
#### E2E Tests
|
||||
|
||||
**Playwright Electron**
|
||||
|
||||
These E2E tests run in electron. There are tests that are skipped if they are ran in a windows, linux, or macos environment. We can use playwright tags to implement test skipping.
|
||||
|
||||
```
|
||||
yarn test:playwright:electron:local
|
||||
yarn test:playwright:electron:windows:local
|
||||
yarn test:playwright:electron:macos:local
|
||||
yarn test:playwright:electron:ubuntu:local
|
||||
```
|
||||
|
||||
> Why does it say local? The CI CD commands that run in the pipeline cannot be ran locally. A single command will not properly setup the testing environment locally.
|
||||
|
||||
#### Some notes on CI
|
||||
|
||||
The tests are broken into snapshot tests and non-snapshot tests, and they run in that order, they automatically commit new snap shots, so if you see an image commit check it was an intended change. If we have non-determinism in the snapshots such that they are always committing new images, hopefully this annoyance makes us fix them asap, if you notice this happening let Kurt know. But for the odd occasion `git reset --hard HEAD~ && git push -f` is your friend.
|
||||
|
||||
How to interpret failing playwright tests?
|
||||
If your tests fail, click through to the action and see that the tests failed on a line that includes `await page.getByTestId('loading').waitFor({ state: 'detached' })`, this means the test fail because the stream never started. It's you choice if you want to re-run the test, or ignore the failure.
|
||||
|
||||
We run on ubuntu and macos, because safari doesn't work on linux because of the dreaded "no RTCPeerConnection variable" error. But linux runs first and then macos for the same reason that we limit the number of parallel tests to 1 because we limit stream connections per user, so tests would start failing we if let them run together.
|
||||
|
||||
If something fails on CI you can download the artifact, unzip it and then open `playwright-report/data/<UUID>.zip` with https://trace.playwright.dev/ to see what happened.
|
||||
|
||||
#### Getting started writing a playwright test in our app
|
||||
|
||||
Besides following the instructions above and using the playwright docs, our app is weird because of the whole stream thing, which means our testing is weird. Because we've just figured out this stuff and therefore docs might go stale quick here's a 15min vid/tutorial
|
||||
|
||||
https://github.com/KittyCAD/modeling-app/assets/29681384/6f5e8e85-1003-4fd9-be7f-f36ce833942d
|
||||
|
||||
<details>
|
||||
|
||||
<summary>
|
||||
PS: for the debug panel, the following JSON is useful for snapping the camera
|
||||
</summary>
|
||||
|
||||
```JSON
|
||||
{"type":"modeling_cmd_req","cmd_id":"054e5472-e5e9-4071-92d7-1ce3bac61956","cmd":{"type":"default_camera_look_at","center":{"x":15,"y":0,"z":0},"up":{"x":0,"y":0,"z":1},"vantage":{"x":30,"y":30,"z":30}}}
|
||||
```
|
||||
|
||||
</details>
|
||||
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
|
||||
|
||||
## KCL
|
||||
|
||||
For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib).
|
||||
|
||||
### Logging
|
||||
|
||||
To display logging (to the terminal or console) set `ZOO_LOG=1`. This will log some warnings and simple performance metrics. To view these in test runs, use `-- --nocapture`.
|
||||
|
||||
To enable memory metrics, build with `--features dhat-heap`.
|
||||
To contribute to the KittyCAD Language, see the [README](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib) for KCL.
|
||||
|
48
biome.json
Normal file
48
biome.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.6.0/schema.json",
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"correctness": {
|
||||
"noUnusedVariables": "error"
|
||||
},
|
||||
"suspicious": {
|
||||
"noExplicitAny": "warn"
|
||||
},
|
||||
"style": {
|
||||
"useBlockStatements": "error",
|
||||
"useShorthandArrayType": "error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentWidth": 2,
|
||||
"indentStyle": "space",
|
||||
"lineWidth": 80,
|
||||
"formatWithErrors": true
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "single",
|
||||
"jsxQuoteStyle": "double",
|
||||
"trailingCommas": "es5",
|
||||
"semicolons": "asNeeded"
|
||||
},
|
||||
"parser": {
|
||||
"unsafeParameterDecoratorsEnabled": true
|
||||
}
|
||||
},
|
||||
"css": {
|
||||
"parser": {
|
||||
"cssModules": true
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"ignore": ["**/*.json"]
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ Compute the absolute value of a number.
|
||||
|
||||
|
||||
```js
|
||||
abs(num: number): number
|
||||
abs(input: number): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ abs(num: number): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the absolute value of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -34,7 +34,7 @@ abs(num: number): number
|
||||
myAngle = -120
|
||||
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [8, 0])
|
||||
|> angledLine(angle = abs(myAngle), length = 5)
|
||||
|> line(end = [-5, 0])
|
||||
|
@ -9,7 +9,7 @@ Compute the arccosine of a number (in radians).
|
||||
|
||||
|
||||
```js
|
||||
acos(num: number): number
|
||||
acos(input: number): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ acos(num: number): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to compute arccosine of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,8 +32,8 @@ acos(num: number): number
|
||||
|
||||
```js
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine(angle = toDegrees(acos(0.5)), length = 10)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = units::toDegrees(acos(0.5)), length = 10)
|
||||
|> line(end = [5, 0])
|
||||
|> line(endAbsolute = [12, 0])
|
||||
|> close()
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -28,11 +28,11 @@ angledLine(
|
||||
|----------|------|-------------|----------|
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
|
||||
| `angle` | [`number`](/docs/kcl/types/number) | Which angle should the line be drawn at? | Yes |
|
||||
| `length` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||
| `lengthX` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||
| `lengthY` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||
| `endAbsoluteX` | [`number`](/docs/kcl/types/number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||
| `endAbsoluteY` | [`number`](/docs/kcl/types/number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||
| `length` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
||||
| `lengthX` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
||||
| `lengthY` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
||||
| `endAbsoluteX` | [`number`](/docs/kcl/types/number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
||||
| `endAbsoluteY` | [`number`](/docs/kcl/types/number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
|
||||
|
||||
### Returns
|
||||
@ -44,7 +44,7 @@ angledLine(
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> yLine(endAbsolute = 15)
|
||||
|> angledLine(angle = 30, length = 15)
|
||||
|> line(end = [8, -10])
|
||||
|
@ -10,8 +10,10 @@ Draw an angled line from the current origin, constructing a line segment such th
|
||||
|
||||
```js
|
||||
angledLineThatIntersects(
|
||||
data: AngledLineThatIntersectsData,
|
||||
sketch: Sketch,
|
||||
angle: number,
|
||||
intersectTag: TagIdentifier,
|
||||
offset?: number,
|
||||
tag?: TagDeclarator,
|
||||
): Sketch
|
||||
```
|
||||
@ -21,9 +23,11 @@ angledLineThatIntersects(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineThatIntersectsData`](/docs/kcl/types/AngledLineThatIntersectsData) | Data for drawing an angled line that intersects with a given line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
|
||||
| `angle` | [`number`](/docs/kcl/types/number) | Which angle should the line be drawn at? | Yes |
|
||||
| `intersectTag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the line to intersect with | Yes |
|
||||
| `offset` | [`number`](/docs/kcl/types/number) | The offset from the intersecting line. Defaults to 0. | No |
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -34,15 +38,11 @@ angledLineThatIntersects(
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(endAbsolute = [5, 10])
|
||||
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|
||||
|> line(endAbsolute = [0, 20])
|
||||
|> angledLineThatIntersects({
|
||||
angle = 80,
|
||||
intersectTag = lineToIntersect,
|
||||
offset = 10
|
||||
}, %)
|
||||
|> angledLineThatIntersects(angle = 80, intersectTag = lineToIntersect, offset = 10)
|
||||
|> close()
|
||||
|
||||
example = extrude(exampleSketch, length = 10)
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ Compute the arcsine of a number (in radians).
|
||||
|
||||
|
||||
```js
|
||||
asin(num: number): number
|
||||
asin(input: number): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ asin(num: number): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to compute arcsine of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,8 +32,8 @@ asin(num: number): number
|
||||
|
||||
```js
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine(angle = toDegrees(asin(0.5)), length = 20)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = units::toDegrees(asin(0.5)), length = 20)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
40
docs/kcl/assertIs.md
Normal file
40
docs/kcl/assertIs.md
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -6,10 +6,10 @@ layout: manual
|
||||
|
||||
Compute the arctangent of a number (in radians).
|
||||
|
||||
|
||||
Consider using `atan2()` instead for the true inverse of tangent.
|
||||
|
||||
```js
|
||||
atan(num: number): number
|
||||
atan(input: number): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ atan(num: number): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to compute arctangent of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,8 +32,8 @@ atan(num: number): number
|
||||
|
||||
```js
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine(angle = toDegrees(atan(1.25)), length = 20)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = units::toDegrees(atan(1.25)), length = 20)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|
||||
|
@ -24,8 +24,8 @@ atan2(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `y` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `x` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `y` | [`number`](/docs/kcl/types/number) | Y | Yes |
|
||||
| `x` | [`number`](/docs/kcl/types/number) | X | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -36,8 +36,8 @@ atan2(
|
||||
|
||||
```js
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine(angle = toDegrees(atan2(1.25, 2)), length = 20)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = units::toDegrees(atan2(y = 1.25, x = 2)), length = 20)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|
||||
|
@ -10,8 +10,10 @@ Draw a smooth, continuous, curved line segment from the current origin to the de
|
||||
|
||||
```js
|
||||
bezierCurve(
|
||||
data: BezierData,
|
||||
sketch: Sketch,
|
||||
control1: [number],
|
||||
control2: [number],
|
||||
end: [number],
|
||||
tag?: TagDeclarator,
|
||||
): Sketch
|
||||
```
|
||||
@ -21,9 +23,11 @@ bezierCurve(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`BezierData`](/docs/kcl/types/BezierData) | Data to draw a bezier curve. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
|
||||
| `control1` | [`[number]`](/docs/kcl/types/number) | First control point for the cubic | Yes |
|
||||
| `control2` | [`[number]`](/docs/kcl/types/number) | Second control point for the cubic | Yes |
|
||||
| `end` | [`[number]`](/docs/kcl/types/number) | How far away (along the X and Y axes) should this line go? | Yes |
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -34,13 +38,9 @@ bezierCurve(
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> bezierCurve({
|
||||
to = [10, 10],
|
||||
control1 = [5, 0],
|
||||
control2 = [5, 10]
|
||||
}, %)
|
||||
|> bezierCurve(control1 = [5, 0], control2 = [5, 10], end = [10, 10])
|
||||
|> line(endAbsolute = [10, 0])
|
||||
|> close()
|
||||
|
||||
|
@ -9,7 +9,7 @@ Compute the smallest integer greater than or equal to a number.
|
||||
|
||||
|
||||
```js
|
||||
ceil(num: number): number
|
||||
ceil(input: number): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ ceil(num: number): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to round. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,7 +32,7 @@ ceil(num: number): number
|
||||
|
||||
```js
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(endAbsolute = [12, 10])
|
||||
|> line(end = [ceil(7.02986), 0])
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
File diff suppressed because one or more lines are too long
258
docs/kcl/clone.md
Normal file
258
docs/kcl/clone.md
Normal file
File diff suppressed because one or more lines are too long
@ -32,7 +32,7 @@ close(
|
||||
|
||||
```js
|
||||
startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 10])
|
||||
|> line(end = [10, 0])
|
||||
|> close()
|
||||
@ -43,7 +43,7 @@ startSketchOn(XZ)
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(-XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> close()
|
||||
|
@ -9,6 +9,8 @@ layout: manual
|
||||
|
||||
### `std`
|
||||
|
||||
- [`END`](/docs/kcl/consts/std-END)
|
||||
- [`START`](/docs/kcl/consts/std-START)
|
||||
- [`X`](/docs/kcl/consts/std-X)
|
||||
- [`XY`](/docs/kcl/consts/std-XY)
|
||||
- [`XZ`](/docs/kcl/consts/std-XZ)
|
||||
|
15
docs/kcl/consts/std-END.md
Normal file
15
docs/kcl/consts/std-END.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
title: "std::END"
|
||||
excerpt: "Identifies the ending face of an extrusion. I.e., the new face created by an extrusion."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Identifies the ending face of an extrusion. I.e., the new face created by an extrusion.
|
||||
|
||||
|
||||
|
||||
```js
|
||||
std::END: string = 'end'
|
||||
```
|
||||
|
||||
|
15
docs/kcl/consts/std-START.md
Normal file
15
docs/kcl/consts/std-START.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
title: "std::START"
|
||||
excerpt: "Identifies the starting face of an extrusion. I.e., the face which is extruded."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Identifies the starting face of an extrusion. I.e., the face which is extruded.
|
||||
|
||||
|
||||
|
||||
```js
|
||||
std::START: string = 'start'
|
||||
```
|
||||
|
||||
|
@ -16,7 +16,7 @@ std::math::E: number = 2.71828182845904523536028747135266250_
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 30,
|
||||
length = 2 * E ^ 2,
|
||||
|
@ -9,7 +9,7 @@ The value of `pi`, Archimedes’ constant (π).
|
||||
|
||||
|
||||
```js
|
||||
std::math::PI: number = 3.14159265358979323846264338327950288_
|
||||
std::math::PI: number(_?) = 3.14159265358979323846264338327950288_?
|
||||
```
|
||||
|
||||
### Examples
|
||||
@ -18,7 +18,7 @@ std::math::PI: number = 3.14159265358979323846264338327950288_
|
||||
circumference = 70
|
||||
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> circle(center = [0, 0], radius = circumference / (2 * PI))
|
||||
|> circle(center = [0, 0], radius = (circumference / (2 * PI)): number(mm))
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
```
|
||||
|
@ -16,7 +16,7 @@ std::math::TAU: number = 6.28318530717958647692528676655900577_
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 50,
|
||||
length = 10 * TAU,
|
||||
|
@ -29,7 +29,7 @@ e(): number
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 30, length = 2 * e() ^ 2)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|
@ -40,20 +40,12 @@ extrude(
|
||||
|
||||
```js
|
||||
example = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> arc({
|
||||
angleStart = 120,
|
||||
angleEnd = 0,
|
||||
radius = 5
|
||||
}, %)
|
||||
|> arc(angleStart = 120, angleEnd = 0, radius = 5)
|
||||
|> line(end = [5, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> bezierCurve({
|
||||
control1 = [-10, 0],
|
||||
control2 = [2, 10],
|
||||
to = [-5, 10]
|
||||
}, %)
|
||||
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|
||||
|> line(end = [-5, -2])
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
@ -63,19 +55,11 @@ example = startSketchOn(XZ)
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([-10, 0], %)
|
||||
|> arc({
|
||||
angleStart = 120,
|
||||
angleEnd = -60,
|
||||
radius = 5
|
||||
}, %)
|
||||
|> startProfile(at = [-10, 0])
|
||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [5, 0])
|
||||
|> bezierCurve({
|
||||
control1 = [-3, 0],
|
||||
control2 = [2, 10],
|
||||
to = [-5, 10]
|
||||
}, %)
|
||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||
|> line(end = [-4, 10])
|
||||
|> line(end = [-5, -2])
|
||||
|> close()
|
||||
@ -87,19 +71,11 @@ example = extrude(exampleSketch, length = 10)
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([-10, 0], %)
|
||||
|> arc({
|
||||
angleStart = 120,
|
||||
angleEnd = -60,
|
||||
radius = 5
|
||||
}, %)
|
||||
|> startProfile(at = [-10, 0])
|
||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [5, 0])
|
||||
|> bezierCurve({
|
||||
control1 = [-3, 0],
|
||||
control2 = [2, 10],
|
||||
to = [-5, 10]
|
||||
}, %)
|
||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||
|> line(end = [-4, 10])
|
||||
|> line(end = [-5, -2])
|
||||
|> close()
|
||||
@ -111,19 +87,11 @@ example = extrude(exampleSketch, length = 20, symmetric = true)
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([-10, 0], %)
|
||||
|> arc({
|
||||
angleStart = 120,
|
||||
angleEnd = -60,
|
||||
radius = 5
|
||||
}, %)
|
||||
|> startProfile(at = [-10, 0])
|
||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [5, 0])
|
||||
|> bezierCurve({
|
||||
control1 = [-3, 0],
|
||||
control2 = [2, 10],
|
||||
to = [-5, 10]
|
||||
}, %)
|
||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||
|> line(end = [-4, 10])
|
||||
|> line(end = [-5, -2])
|
||||
|> close()
|
||||
|
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ Compute the largest integer less than or equal to a number.
|
||||
|
||||
|
||||
```js
|
||||
floor(num: number): number
|
||||
floor(input: number): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ floor(num: number): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to round. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,7 +32,7 @@ floor(num: number): number
|
||||
|
||||
```js
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(endAbsolute = [12, 10])
|
||||
|> line(end = [floor(7.02986), 0])
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from centimeters to the current default unit."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
**WARNING:** This function is deprecated.
|
||||
|
||||
Converts a number from centimeters to the current default unit.
|
||||
|
||||
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions.
|
||||
|
||||
No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters.
|
||||
|
||||
For example, if the current file uses inches, `fromCm(1)` will return `0.393701`. If the current file uses millimeters, `fromCm(1)` will return `10`. If the current file uses centimeters, `fromCm(1)` will return `1`.
|
||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from feet to the current default unit."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
**WARNING:** This function is deprecated.
|
||||
|
||||
Converts a number from feet to the current default unit.
|
||||
|
||||
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions.
|
||||
|
||||
No matter what units the current file uses, this function will always return a number equivalent to the input in feet.
|
||||
|
||||
For example, if the current file uses inches, `fromFt(1)` will return `12`. If the current file uses millimeters, `fromFt(1)` will return `304.8`. If the current file uses feet, `fromFt(1)` will return `1`.
|
||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from inches to the current default unit."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
**WARNING:** This function is deprecated.
|
||||
|
||||
Converts a number from inches to the current default unit.
|
||||
|
||||
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions.
|
||||
|
||||
No matter what units the current file uses, this function will always return a number equivalent to the input in inches.
|
||||
|
||||
For example, if the current file uses inches, `fromInches(1)` will return `1`. If the current file uses millimeters, `fromInches(1)` will return `25.4`.
|
||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from meters to the current default unit."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
**WARNING:** This function is deprecated.
|
||||
|
||||
Converts a number from meters to the current default unit.
|
||||
|
||||
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions.
|
||||
|
||||
No matter what units the current file uses, this function will always return a number equivalent to the input in meters.
|
||||
|
||||
For example, if the current file uses inches, `fromM(1)` will return `39.3701`. If the current file uses millimeters, `fromM(1)` will return `1000`. If the current file uses meters, `fromM(1)` will return `1`.
|
||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from mm to the current default unit."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
**WARNING:** This function is deprecated.
|
||||
|
||||
Converts a number from mm to the current default unit.
|
||||
|
||||
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions.
|
||||
|
||||
No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters.
|
||||
|
||||
For example, if the current file uses inches, `fromMm(1)` will return `1/25.4`. If the current file uses millimeters, `fromMm(1)` will return `1`.
|
||||
|
@ -4,8 +4,12 @@ excerpt: "Converts a number from yards to the current default unit."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
**WARNING:** This function is deprecated.
|
||||
|
||||
Converts a number from yards to the current default unit.
|
||||
|
||||
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions.
|
||||
|
||||
No matter what units the current file uses, this function will always return a number equivalent to the input in yards.
|
||||
|
||||
For example, if the current file uses inches, `fromYd(1)` will return `36`. If the current file uses millimeters, `fromYd(1)` will return `914.4`. If the current file uses yards, `fromYd(1)` will return `1`.
|
||||
|
@ -32,7 +32,7 @@ getCommonEdge(faces: [TagIdentifier]): Uuid
|
||||
|
||||
scale = 20
|
||||
part001 = startSketchOn(XY)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [0, scale])
|
||||
|> line(end = [scale, 0])
|
||||
|> line(end = [0, -scale])
|
||||
|
@ -9,7 +9,7 @@ Get the next adjacent edge to the edge given.
|
||||
|
||||
|
||||
```js
|
||||
getNextAdjacentEdge(tag: TagIdentifier): Uuid
|
||||
getNextAdjacentEdge(edge: TagIdentifier): Uuid
|
||||
```
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ getNextAdjacentEdge(tag: TagIdentifier): Uuid
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
|
||||
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the next adjacent edge of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -28,7 +28,7 @@ getNextAdjacentEdge(tag: TagIdentifier): Uuid
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> angledLine(angle = 60, length = 10)
|
||||
|> angledLine(angle = 120, length = 10)
|
||||
|
@ -9,7 +9,7 @@ Get the opposite edge to the edge given.
|
||||
|
||||
|
||||
```js
|
||||
getOppositeEdge(tag: TagIdentifier): Uuid
|
||||
getOppositeEdge(edge: TagIdentifier): Uuid
|
||||
```
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ getOppositeEdge(tag: TagIdentifier): Uuid
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
|
||||
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the opposite edge of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -28,7 +28,7 @@ getOppositeEdge(tag: TagIdentifier): Uuid
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> angledLine(angle = 60, length = 10)
|
||||
|> angledLine(angle = 120, length = 10)
|
||||
|
@ -9,7 +9,7 @@ Get the previous adjacent edge to the edge given.
|
||||
|
||||
|
||||
```js
|
||||
getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
|
||||
getPreviousAdjacentEdge(edge: TagIdentifier): Uuid
|
||||
```
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
|
||||
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the previous adjacent edge of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -28,7 +28,7 @@ getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> angledLine(angle = 60, length = 10)
|
||||
|> angledLine(angle = 120, length = 10)
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -22,16 +22,8 @@ layout: manual
|
||||
* [`string`](kcl/types/string)
|
||||
* [`tag`](kcl/types/tag)
|
||||
* **std**
|
||||
* [`Axis2d`](kcl/types/Axis2d)
|
||||
* [`Axis3d`](kcl/types/Axis3d)
|
||||
* [`Edge`](kcl/types/Edge)
|
||||
* [`Face`](kcl/types/Face)
|
||||
* [`Helix`](kcl/types/Helix)
|
||||
* [`Plane`](kcl/types/Plane)
|
||||
* [`Point2d`](kcl/types/Point2d)
|
||||
* [`Point3d`](kcl/types/Point3d)
|
||||
* [`Sketch`](kcl/types/Sketch)
|
||||
* [`Solid`](kcl/types/Solid)
|
||||
* [`END`](kcl/consts/std-END)
|
||||
* [`START`](kcl/consts/std-START)
|
||||
* [`X`](kcl/consts/std-X)
|
||||
* [`XY`](kcl/consts/std-XY)
|
||||
* [`XZ`](kcl/consts/std-XZ)
|
||||
@ -40,43 +32,29 @@ layout: manual
|
||||
* [`Z`](kcl/consts/std-Z)
|
||||
* [`abs`](kcl/abs)
|
||||
* [`acos`](kcl/acos)
|
||||
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
|
||||
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
|
||||
* [`angledLine`](kcl/angledLine)
|
||||
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
|
||||
* [`appearance`](kcl/appearance)
|
||||
* [`arc`](kcl/arc)
|
||||
* [`arcTo`](kcl/arcTo)
|
||||
* [`asin`](kcl/asin)
|
||||
* [`assert`](kcl/assert)
|
||||
* [`assertEqual`](kcl/assertEqual)
|
||||
* [`assertGreaterThan`](kcl/assertGreaterThan)
|
||||
* [`assertGreaterThanOrEq`](kcl/assertGreaterThanOrEq)
|
||||
* [`assertLessThan`](kcl/assertLessThan)
|
||||
* [`assertLessThanOrEq`](kcl/assertLessThanOrEq)
|
||||
* [`assertIs`](kcl/assertIs)
|
||||
* [`atan`](kcl/atan)
|
||||
* [`atan2`](kcl/atan2)
|
||||
* [`bezierCurve`](kcl/bezierCurve)
|
||||
* [`ceil`](kcl/ceil)
|
||||
* [`chamfer`](kcl/chamfer)
|
||||
* [`circleThreePoint`](kcl/circleThreePoint)
|
||||
* [`clone`](kcl/clone)
|
||||
* [`close`](kcl/close)
|
||||
* [`extrude`](kcl/extrude)
|
||||
* [`fillet`](kcl/fillet)
|
||||
* [`floor`](kcl/floor)
|
||||
* [`fromCm`](kcl/fromCm)
|
||||
* [`fromFt`](kcl/fromFt)
|
||||
* [`fromInches`](kcl/fromInches)
|
||||
* [`fromM`](kcl/fromM)
|
||||
* [`fromMm`](kcl/fromMm)
|
||||
* [`fromYd`](kcl/fromYd)
|
||||
* [`getCommonEdge`](kcl/getCommonEdge)
|
||||
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
||||
* [`helix`](kcl/std-helix)
|
||||
* [`hole`](kcl/hole)
|
||||
* [`hollow`](kcl/hollow)
|
||||
* [`intersect`](kcl/intersect)
|
||||
* [`involuteCircular`](kcl/involuteCircular)
|
||||
* [`lastSegX`](kcl/lastSegX)
|
||||
* [`lastSegY`](kcl/lastSegY)
|
||||
* [`legAngX`](kcl/legAngX)
|
||||
@ -91,7 +69,7 @@ layout: manual
|
||||
* [`map`](kcl/map)
|
||||
* [`max`](kcl/max)
|
||||
* [`min`](kcl/min)
|
||||
* [`offsetPlane`](kcl/offsetPlane)
|
||||
* [`offsetPlane`](kcl/std-offsetPlane)
|
||||
* [`patternCircular2d`](kcl/patternCircular2d)
|
||||
* [`patternCircular3d`](kcl/patternCircular3d)
|
||||
* [`patternLinear2d`](kcl/patternLinear2d)
|
||||
@ -119,18 +97,16 @@ layout: manual
|
||||
* [`segStart`](kcl/segStart)
|
||||
* [`segStartX`](kcl/segStartX)
|
||||
* [`segStartY`](kcl/segStartY)
|
||||
* [`shell`](kcl/shell)
|
||||
* [`sqrt`](kcl/sqrt)
|
||||
* [`startProfileAt`](kcl/startProfileAt)
|
||||
* [`startProfile`](kcl/startProfile)
|
||||
* [`startSketchOn`](kcl/startSketchOn)
|
||||
* [`subtract`](kcl/subtract)
|
||||
* [`subtract2d`](kcl/subtract2d)
|
||||
* [`sweep`](kcl/sweep)
|
||||
* [`tangentToEnd`](kcl/tangentToEnd)
|
||||
* [`tangentialArc`](kcl/tangentialArc)
|
||||
* [`tangentialArcTo`](kcl/tangentialArcTo)
|
||||
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
|
||||
* [`toDegrees`](kcl/toDegrees)
|
||||
* [`toRadians`](kcl/toRadians)
|
||||
* [`translate`](kcl/translate)
|
||||
* [`union`](kcl/union)
|
||||
* [`xLine`](kcl/xLine)
|
||||
* [`yLine`](kcl/yLine)
|
||||
* **std::math**
|
||||
@ -144,8 +120,33 @@ layout: manual
|
||||
* **std::sketch**
|
||||
* [`circle`](kcl/std-sketch-circle)
|
||||
* [`mirror2d`](kcl/std-sketch-mirror2d)
|
||||
* **std::solid**
|
||||
* [`chamfer`](kcl/std-solid-chamfer)
|
||||
* [`fillet`](kcl/std-solid-fillet)
|
||||
* [`hollow`](kcl/std-solid-hollow)
|
||||
* [`shell`](kcl/std-solid-shell)
|
||||
* **std::turns**
|
||||
* [`turns::HALF_TURN`](kcl/consts/std-turns-HALF_TURN)
|
||||
* [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN)
|
||||
* [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN)
|
||||
* [`turns::ZERO`](kcl/consts/std-turns-ZERO)
|
||||
* **std::types**
|
||||
* [`Axis2d`](kcl/types/Axis2d)
|
||||
* [`Axis3d`](kcl/types/Axis3d)
|
||||
* [`Edge`](kcl/types/Edge)
|
||||
* [`Face`](kcl/types/Face)
|
||||
* [`Helix`](kcl/types/Helix)
|
||||
* [`Plane`](kcl/types/Plane)
|
||||
* [`Point2d`](kcl/types/Point2d)
|
||||
* [`Point3d`](kcl/types/Point3d)
|
||||
* [`Sketch`](kcl/types/Sketch)
|
||||
* [`Solid`](kcl/types/Solid)
|
||||
* **std::units**
|
||||
* [`units::toCentimeters`](kcl/std-units-toCentimeters)
|
||||
* [`units::toDegrees`](kcl/std-units-toDegrees)
|
||||
* [`units::toFeet`](kcl/std-units-toFeet)
|
||||
* [`units::toInches`](kcl/std-units-toInches)
|
||||
* [`units::toMeters`](kcl/std-units-toMeters)
|
||||
* [`units::toMillimeters`](kcl/std-units-toMillimeters)
|
||||
* [`units::toRadians`](kcl/std-units-toRadians)
|
||||
* [`units::toYards`](kcl/std-units-toYards)
|
||||
|
@ -34,7 +34,7 @@ int(num: number): number
|
||||
|
||||
```js
|
||||
n = int(ceil(5 / 2))
|
||||
assertEqual(n, 3, 0.0001, "5/2 = 2.5, rounded up makes 3")
|
||||
assert(n, isEqualTo = 3, error = "5/2 = 2.5, rounded up makes 3")
|
||||
// Draw n cylinders.
|
||||
startSketchOn(XZ)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|
File diff suppressed because one or more lines are too long
57
docs/kcl/involuteCircular.md
Normal file
57
docs/kcl/involuteCircular.md
Normal file
File diff suppressed because one or more lines are too long
@ -21,4 +21,6 @@ once fixed in engine will just start working here with no language changes.
|
||||
- **Chamfers**: Chamfers cannot intersect, you will get an error. Only simple
|
||||
chamfer cases work currently.
|
||||
|
||||
- **Appearance**: Changing the appearance on a loft does not work.
|
||||
- **Appearance**: Changing the appearance on a loft does not work.
|
||||
|
||||
- **CSG Booleans**: Coplanar (bodies that share a plane) unions, subtractions, and intersections are not currently supported.
|
||||
|
@ -28,7 +28,7 @@ lastSegX(sketch: Sketch): number
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [5, 0])
|
||||
|> line(end = [20, 5])
|
||||
|> line(end = [lastSegX(%), 0])
|
||||
|
@ -28,7 +28,7 @@ lastSegY(sketch: Sketch): number
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [5, 0])
|
||||
|> line(end = [20, 5])
|
||||
|> line(end = [0, lastSegY(%)])
|
||||
|
@ -24,8 +24,8 @@ legAngX(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
|
||||
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -35,7 +35,7 @@ legAngX(
|
||||
### Examples
|
||||
|
||||
```js
|
||||
legAngX(5, 3)
|
||||
legAngX(hypotenuse = 5, leg = 3)
|
||||
```
|
||||
|
||||
|
||||
|
@ -24,8 +24,8 @@ legAngY(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
|
||||
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -35,7 +35,7 @@ legAngY(
|
||||
### Examples
|
||||
|
||||
```js
|
||||
legAngY(5, 3)
|
||||
legAngY(hypotenuse = 5, leg = 3)
|
||||
```
|
||||
|
||||
|
||||
|
@ -24,8 +24,8 @@ legLen(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
|
||||
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -35,7 +35,7 @@ legLen(
|
||||
### Examples
|
||||
|
||||
```js
|
||||
legLen(5, 3)
|
||||
legLen(hypotenuse = 5, leg = 3)
|
||||
```
|
||||
|
||||
|
||||
|
@ -36,8 +36,8 @@ line(
|
||||
|
||||
```js
|
||||
triangle = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
// The 'end' argument means it ends at exactly [10, 0].
|
||||
|> startProfile(at = [0, 0])
|
||||
// The END argument means it ends at exactly [10, 0].
|
||||
// This is an absolute measurement, it is NOT relative to
|
||||
// the start of the sketch.
|
||||
|> line(endAbsolute = [10, 0])
|
||||
@ -47,7 +47,7 @@ triangle = startSketchOn(XZ)
|
||||
|> extrude(length = 5)
|
||||
|
||||
box = startSketchOn(XZ)
|
||||
|> startProfileAt([10, 10], %)
|
||||
|> startProfile(at = [10, 10])
|
||||
// The 'to' argument means move the pen this much.
|
||||
// So, [10, 0] is a relative distance away from the current point.
|
||||
|> line(end = [10, 0])
|
||||
|
@ -9,7 +9,7 @@ Compute the natural logarithm of the number.
|
||||
|
||||
|
||||
```js
|
||||
ln(num: number): number
|
||||
ln(input: number): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ ln(num: number): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the logarithm of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,7 +32,7 @@ ln(num: number): number
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [ln(100), 15])
|
||||
|> line(end = [5, -6])
|
||||
|> line(end = [-10, -10])
|
||||
|
@ -43,7 +43,7 @@ loft(
|
||||
```js
|
||||
// Loft a square and a triangle.
|
||||
squareSketch = startSketchOn(XY)
|
||||
|> startProfileAt([-100, 200], %)
|
||||
|> startProfile(at = [-100, 200])
|
||||
|> line(end = [200, 0])
|
||||
|> line(end = [0, -200])
|
||||
|> line(end = [-200, 0])
|
||||
@ -51,7 +51,7 @@ squareSketch = startSketchOn(XY)
|
||||
|> close()
|
||||
|
||||
triangleSketch = startSketchOn(offsetPlane(XY, offset = 75))
|
||||
|> startProfileAt([0, 125], %)
|
||||
|> startProfile(at = [0, 125])
|
||||
|> line(end = [-15, -30])
|
||||
|> line(end = [30, 0])
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -65,7 +65,7 @@ loft([squareSketch, triangleSketch])
|
||||
```js
|
||||
// Loft a square, a circle, and another circle.
|
||||
squareSketch = startSketchOn(XY)
|
||||
|> startProfileAt([-100, 200], %)
|
||||
|> startProfile(at = [-100, 200])
|
||||
|> line(end = [200, 0])
|
||||
|> line(end = [0, -200])
|
||||
|> line(end = [-200, 0])
|
||||
@ -90,7 +90,7 @@ loft([
|
||||
```js
|
||||
// Loft a square, a circle, and another circle with options.
|
||||
squareSketch = startSketchOn(XY)
|
||||
|> startProfileAt([-100, 200], %)
|
||||
|> startProfile(at = [-100, 200])
|
||||
|> line(end = [200, 0])
|
||||
|> line(end = [0, -200])
|
||||
|> line(end = [-200, 0])
|
||||
|
@ -10,7 +10,7 @@ The result might not be correctly rounded owing to implementation details; `log2
|
||||
|
||||
```js
|
||||
log(
|
||||
num: number,
|
||||
input: number,
|
||||
base: number,
|
||||
): number
|
||||
```
|
||||
@ -24,8 +24,8 @@ log(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `base` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the logarithm of. | Yes |
|
||||
| `base` | [`number`](/docs/kcl/types/number) | The base of the logarithm. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -36,8 +36,8 @@ log(
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line(end = [log(100, 5), 0])
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [log(100, base = 5), 0])
|
||||
|> line(end = [5, 8])
|
||||
|> line(end = [-10, 0])
|
||||
|> close()
|
||||
|
@ -32,7 +32,7 @@ log10(num: number): number
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [log10(100), 0])
|
||||
|> line(end = [5, 8])
|
||||
|> line(end = [-10, 0])
|
||||
|
@ -9,7 +9,7 @@ Compute the base 2 logarithm of the number.
|
||||
|
||||
|
||||
```js
|
||||
log2(num: number): number
|
||||
log2(input: number): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ log2(num: number): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the logarithm of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,7 +32,7 @@ log2(num: number): number
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [log2(100), 0])
|
||||
|> line(end = [5, 8])
|
||||
|> line(end = [-10, 0])
|
||||
|
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ Compute the maximum of the given arguments.
|
||||
|
||||
|
||||
```js
|
||||
max(args: [number]): number
|
||||
max(input: [number]): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ max(args: [number]): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `args` | [`[number]`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`[number]`](/docs/kcl/types/number) | An array of numbers to compute the maximum of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,8 +32,8 @@ max(args: [number]): number
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine(angle = 70, length = max(15, 31, 4, 13, 22))
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 70, length = max([15, 31, 4, 13, 22]))
|
||||
|> line(end = [20, 0])
|
||||
|> close()
|
||||
|
||||
|
@ -9,7 +9,7 @@ Compute the minimum of the given arguments.
|
||||
|
||||
|
||||
```js
|
||||
min(args: [number]): number
|
||||
min(input: [number]): number
|
||||
```
|
||||
|
||||
### Tags
|
||||
@ -21,7 +21,7 @@ min(args: [number]): number
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `args` | [`[number]`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`[number]`](/docs/kcl/types/number) | An array of numbers to compute the minimum of. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -32,8 +32,8 @@ min(args: [number]): number
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine(angle = 70, length = min(15, 31, 4, 13, 22))
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 70, length = min([15, 31, 4, 13, 22]))
|
||||
|> line(end = [20, 0])
|
||||
|> close()
|
||||
|
||||
|
@ -10,7 +10,7 @@ isolated from other files as a separate module.
|
||||
When you define a function, you can use `export` before it to make it available
|
||||
to other modules.
|
||||
|
||||
```
|
||||
```kcl
|
||||
// util.kcl
|
||||
export fn increment(x) {
|
||||
return x + 1
|
||||
@ -31,11 +31,11 @@ Imported files _must_ be in the same project so that units are uniform across
|
||||
modules. This means that it must be in the same directory.
|
||||
|
||||
Import statements must be at the top-level of a file. It is not allowed to have
|
||||
an `import` statement inside a function or in the body of an if-else.
|
||||
an `import` statement inside a function or in the body of an if‑else.
|
||||
|
||||
Multiple functions can be exported in a file.
|
||||
|
||||
```
|
||||
```kcl
|
||||
// util.kcl
|
||||
export fn increment(x) {
|
||||
return x + 1
|
||||
@ -58,6 +58,215 @@ Imported symbols can be renamed for convenience or to avoid name collisions.
|
||||
import increment as inc, decrement as dec from "util.kcl"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Functions vs `clone`
|
||||
|
||||
There are two common patterns for re‑using geometry:
|
||||
|
||||
1. **Wrap the construction in a function** – flexible and fully parametric.
|
||||
2. **Duplicate an existing object with `clone`** – lightning‑fast, but an exact
|
||||
duplicate.
|
||||
|
||||
### Parametric function example
|
||||
|
||||
```kcl
|
||||
fn cube(center) {
|
||||
return startSketchOn(XY)
|
||||
|> startProfile(at = [center[0] - 10, center[1] - 10])
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
||||
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
||||
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
}
|
||||
|
||||
myCube = cube([0, 0])
|
||||
```
|
||||
|
||||
*Pros*
|
||||
- Any argument can be a parameter – size, position, appearance, etc.
|
||||
- Works great inside loops, arrays, or optimisation sweeps.
|
||||
|
||||
*Cons*
|
||||
- Every invocation rebuilds the entire feature tree.
|
||||
- **Slower** than a straight duplicate – each call is its own render job.
|
||||
|
||||
### `clone` example
|
||||
|
||||
```kcl
|
||||
sketch001 = startSketchOn(-XZ)
|
||||
|> circle(center = [0, 0], radius = 10)
|
||||
|> extrude(length = 5)
|
||||
|> appearance(color = "#ff0000", metalness = 90, roughness = 90)
|
||||
|
||||
sketch002 = clone(sketch001) // ✓ instant copy
|
||||
```
|
||||
|
||||
*Pros*
|
||||
- Roughly an O(1) operation – we just duplicate the underlying engine handle.
|
||||
- Perfect when you need ten identical bolts or two copies of the same imported STEP file.
|
||||
|
||||
*Cons*
|
||||
- **Not parametric** – the clone is exactly the same shape as the source.
|
||||
- If you need to tweak dimensions per‑instance, you’re back to a function.
|
||||
|
||||
> **Rule of thumb** – Reach for `clone` when the geometry is already what you want. Reach for a function when you need customisation.
|
||||
|
||||
---
|
||||
|
||||
## Module‑level parallelism
|
||||
|
||||
Under the hood, the Design Studio runs **every module in parallel** where it can. This means:
|
||||
|
||||
- The top‑level code of `foo.kcl`, `bar.kcl`, and `baz.kcl` all start executing immediately and concurrently.
|
||||
- Imports that read foreign files (STEP/OBJ/…) overlap their I/O and background render.
|
||||
- CPU‑bound calculations in separate modules get their own worker threads.
|
||||
|
||||
### Why modules beat one‑big‑file
|
||||
|
||||
If you shoe‑horn everything into `main.kcl`, each statement runs sequentially:
|
||||
|
||||
```norun
|
||||
import "big.step" as gizmo // blocks main while reading
|
||||
|
||||
gizmo |> translate(x=50) // blocks again while waiting for render
|
||||
```
|
||||
|
||||
Split `gizmo` into its own file and the read/render can overlap whatever else `main.kcl` is doing.
|
||||
|
||||
```norun
|
||||
// gizmo.kcl (worker A)
|
||||
import "big.step"
|
||||
|
||||
// main.kcl (worker B)
|
||||
import "gizmo.kcl" as gizmo // non‑blocking
|
||||
|
||||
// ... other setup ...
|
||||
|
||||
gizmo |> translate(x=50) // only blocks here
|
||||
```
|
||||
|
||||
### Gotcha: defining but **not** calling functions
|
||||
|
||||
Defining a function inside a module is instantaneous – we just record the byte‑code. The heavy lifting happens when the function is **called**. So:
|
||||
|
||||
```norun
|
||||
// util.kcl
|
||||
export fn makeBolt(size) { /* … expensive CAD … */ }
|
||||
```
|
||||
|
||||
If `main.kcl` waits until the very end to call `makeBolt`, *none* of that work was parallelised – you’ve pushed the cost back onto the serial tail of your script.
|
||||
|
||||
**Better:** call it early or move the invocation into another module.
|
||||
|
||||
```norun
|
||||
// bolt_instance.kcl
|
||||
import makeBolt from "util.kcl"
|
||||
bolt = makeBolt(5) // executed in parallel
|
||||
bolt
|
||||
```
|
||||
|
||||
Now `main.kcl` can `import "bolt_instance.kcl" as bolt` and get the result that was rendered while it was busy doing other things.
|
||||
|
||||
---
|
||||
|
||||
## Whole module import
|
||||
|
||||
You can also import the whole module. This is useful if you want to use the
|
||||
result of a module as a variable, like a part.
|
||||
|
||||
```norun
|
||||
import "tests/inputs/cube.kcl" as cube
|
||||
cube
|
||||
|> translate(x=10)
|
||||
```
|
||||
|
||||
This imports the whole module and makes it available as `cube`. You can then
|
||||
use it like any other object. The `cube` variable is now a reference to the
|
||||
result of the module. This means that if you change the module, the `cube`
|
||||
variable will change as well.
|
||||
|
||||
In `cube.kcl`, you cannot have multiple objects. It has to be a single part. If
|
||||
you have multiple objects, you will get an error. This is because the module is
|
||||
expected to return a single object that can be used as a variable.
|
||||
|
||||
The last expression or variable definition becomes the module's return value.
|
||||
The module is expected to return a single object that can be used as a variable
|
||||
by whatever imports it.
|
||||
|
||||
So for example, this is allowed:
|
||||
|
||||
```norun
|
||||
... a bunch of code to create cube and cube2 ...
|
||||
|
||||
myUnion = union([cube, cube2])
|
||||
```
|
||||
|
||||
You can also do this:
|
||||
|
||||
```norun
|
||||
... a bunch of code to create cube and cube2 ...
|
||||
|
||||
union([cube, cube2])
|
||||
```
|
||||
|
||||
Either way, the last line will return the union of the two objects.
|
||||
|
||||
Or what you could do instead is:
|
||||
|
||||
```norun
|
||||
... a bunch of code to create cube and cube2 ...
|
||||
|
||||
myUnion = union([cube, cube2])
|
||||
myUnion
|
||||
```
|
||||
|
||||
This will assign the union of the two objects to a variable, and then return it
|
||||
on the last statement. It's simply another way of doing the same thing.
|
||||
|
||||
The final statement is what's important because it's the return value of the
|
||||
entire module. The module is expected to return a single object that can be used
|
||||
as a variable by the file that imports it.
|
||||
|
||||
---
|
||||
|
||||
## Multiple instances of the same import
|
||||
|
||||
Whether you are importing a file from another CAD system or a KCL file, that
|
||||
file represents object(s) in memory. If you import the same file multiple times,
|
||||
it will only be rendered once.
|
||||
|
||||
If you want to have multiple instances of the same object, you can use the
|
||||
[`clone`](/docs/kcl/clone) function. This will render a new instance of the object in memory.
|
||||
|
||||
```norun
|
||||
import cube from "tests/inputs/cube.kcl"
|
||||
|
||||
cube
|
||||
|> translate(x=10)
|
||||
clone(cube)
|
||||
|> translate(x=20)
|
||||
```
|
||||
|
||||
In the sample above, the `cube` object is imported from a KCL file. The first
|
||||
instance is translated 10 units in the x direction. The second instance is
|
||||
cloned and translated 20 units in the x direction. The two instances are now
|
||||
separate objects in memory, and can be manipulated independently.
|
||||
|
||||
Here is an example with a file from another CAD system:
|
||||
|
||||
```kcl
|
||||
import "tests/inputs/cube.step" as cube
|
||||
|
||||
cube
|
||||
|> translate(x=10)
|
||||
clone(cube)
|
||||
|> translate(x=20)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Importing files from other CAD systems
|
||||
|
||||
`import` can also be used to import files from other CAD systems. The format of the statement is the
|
||||
@ -69,26 +278,18 @@ import "tests/inputs/cube.obj"
|
||||
// Use `cube` just like a KCL object.
|
||||
```
|
||||
|
||||
```norun
|
||||
import "tests/inputs/cube-2.sldprt" as cube
|
||||
```kcl
|
||||
import "tests/inputs/cube.sldprt" as cube
|
||||
|
||||
// Use `cube` just like a KCL object.
|
||||
```
|
||||
|
||||
You can make the file format explicit using a format attribute (useful if using a different
|
||||
extension), e.g.,
|
||||
|
||||
```norun
|
||||
@(format = obj)
|
||||
import "tests/inputs/cube"
|
||||
```
|
||||
|
||||
For formats lacking unit data (such as STL, OBJ, or PLY files), the default
|
||||
unit of measurement is millimeters. Alternatively you may specify the unit
|
||||
by using an attirbute. Likewise, you can also specify a coordinate system. E.g.,
|
||||
by using an attribute. Likewise, you can also specify a coordinate system. E.g.,
|
||||
|
||||
```norun
|
||||
@(unitLength = ft, coords = opengl)
|
||||
```kcl
|
||||
@(lengthUnit = ft, coords = opengl)
|
||||
import "tests/inputs/cube.obj"
|
||||
```
|
||||
|
||||
@ -109,3 +310,56 @@ Coordinate systems:
|
||||
- `zoo` (the default), forward: -Y, up: +Z, handedness: right
|
||||
- `opengl`, forward: +Z, up: +Y, handedness: right
|
||||
- `vulkan`, forward: +Z, up: -Y, handedness: left
|
||||
|
||||
---
|
||||
|
||||
## Performance deep‑dive for foreign‑file imports
|
||||
|
||||
Parallelized foreign‑file imports now let you overlap file reads, initialization,
|
||||
and rendering. To maximize throughput, you need to understand the three distinct
|
||||
stages—reading, initializing (background render start), and invocation (blocking)
|
||||
—and structure your code to defer blocking operations until the end.
|
||||
|
||||
### Foreign import execution stages
|
||||
|
||||
1. **Import (Read / Initialization) Stage**
|
||||
```kcl
|
||||
import "tests/inputs/cube.step" as cube
|
||||
```
|
||||
- Reads the file from disk and makes its API available.
|
||||
- Starts engine rendering but **does not block** your script.
|
||||
- This kick‑starts the render pipeline while you keep executing other code.
|
||||
|
||||
2. **Invocation (Blocking) Stage**
|
||||
```kcl
|
||||
import "tests/inputs/cube.step" as cube
|
||||
|
||||
cube
|
||||
|> translate(z=10) // ← blocks here only
|
||||
```
|
||||
- Any method call (e.g., `translate`, `scale`, `rotate`) waits for the background render to finish before applying transformations.
|
||||
|
||||
### Best practices
|
||||
|
||||
#### 1. Defer blocking calls
|
||||
|
||||
```kcl
|
||||
import "tests/inputs/cube.step" as cube // 1) Read / Background render starts
|
||||
|
||||
|
||||
// --- perform other operations and calculations here ---
|
||||
|
||||
|
||||
cube
|
||||
|> translate(z=10) // 2) Blocks only here
|
||||
```
|
||||
|
||||
#### 2. Split heavy work into separate modules
|
||||
|
||||
Place computationally expensive or IO‑heavy work into its own module so it can render in parallel while `main.kcl` continues.
|
||||
|
||||
#### Future improvements
|
||||
|
||||
Upcoming releases will auto‑analyse dependencies and only block when truly necessary. Until then, explicit deferral will give you the best performance.
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -40,7 +40,7 @@ patternCircular2d(
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([.5, 25], %)
|
||||
|> startProfile(at = [.5, 25])
|
||||
|> line(end = [0, 5])
|
||||
|> line(end = [-1, 0])
|
||||
|> line(end = [0, -5])
|
||||
|
@ -38,7 +38,7 @@ patternLinear3d(
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [0, 2])
|
||||
|> line(end = [3, 1])
|
||||
|> line(end = [0, -4])
|
||||
@ -54,18 +54,18 @@ example = extrude(exampleSketch, length = 1)
|
||||
// Pattern a whole sketch on face.
|
||||
size = 100
|
||||
case = startSketchOn(XY)
|
||||
|> startProfileAt([-size, -size], %)
|
||||
|> startProfile(at = [-size, -size])
|
||||
|> line(end = [2 * size, 0])
|
||||
|> line(end = [0, 2 * size])
|
||||
|> tangentialArcTo([-size, size], %)
|
||||
|> tangentialArc(endAbsolute = [-size, size])
|
||||
|> close(%)
|
||||
|> extrude(length = 65)
|
||||
|
||||
thing1 = startSketchOn(case, 'end')
|
||||
thing1 = startSketchOn(case, face = END)
|
||||
|> circle(center = [-size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
thing2 = startSketchOn(case, 'end')
|
||||
thing2 = startSketchOn(case, face = END)
|
||||
|> circle(center = [size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
@ -85,14 +85,14 @@ patternLinear3d(
|
||||
// Pattern an object on a face.
|
||||
size = 100
|
||||
case = startSketchOn(XY)
|
||||
|> startProfileAt([-size, -size], %)
|
||||
|> startProfile(at = [-size, -size])
|
||||
|> line(end = [2 * size, 0])
|
||||
|> line(end = [0, 2 * size])
|
||||
|> tangentialArcTo([-size, size], %)
|
||||
|> tangentialArc(endAbsolute = [-size, size])
|
||||
|> close(%)
|
||||
|> extrude(length = 65)
|
||||
|
||||
thing1 = startSketchOn(case, 'end')
|
||||
thing1 = startSketchOn(case, face = END)
|
||||
|> circle(center = [-size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
|
@ -102,7 +102,7 @@ fn cube(length, center) {
|
||||
p3 = [l + x, -l + y]
|
||||
|
||||
return startSketchOn(XY)
|
||||
|> startProfileAt(p0, %)
|
||||
|> startProfile(at = p0)
|
||||
|> line(endAbsolute = p1)
|
||||
|> line(endAbsolute = p2)
|
||||
|> line(endAbsolute = p3)
|
||||
@ -117,7 +117,11 @@ fn transform(i) {
|
||||
// Move down each time.
|
||||
translate = [0, 0, -i * width],
|
||||
// Make the cube longer, wider and flatter each time.
|
||||
scale = [pow(1.1, i), pow(1.1, i), pow(0.9, i)],
|
||||
scale = [
|
||||
pow(1.1, exp = i),
|
||||
pow(1.1, exp = i),
|
||||
pow(0.9, exp = i)
|
||||
],
|
||||
// Turn by 15 degrees each time.
|
||||
rotation = { angle = 15 * i, origin = "local" }
|
||||
}
|
||||
@ -140,7 +144,7 @@ fn cube(length, center) {
|
||||
p3 = [l + x, -l + y]
|
||||
|
||||
return startSketchOn(XY)
|
||||
|> startProfileAt(p0, %)
|
||||
|> startProfile(at = p0)
|
||||
|> line(endAbsolute = p1)
|
||||
|> line(endAbsolute = p2)
|
||||
|> line(endAbsolute = p3)
|
||||
@ -174,7 +178,7 @@ t = 0.005 // taper factor [0-1)
|
||||
// Defines how to modify each layer of the vase.
|
||||
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
||||
fn transform(replicaId) {
|
||||
scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
|
||||
scale = r * abs(1 - (t * replicaId)) * (5 + cos((replicaId / 8): number(rad)))
|
||||
return {
|
||||
translate = [0, 0, replicaId * 10],
|
||||
scale = [scale, scale, 0]
|
||||
@ -204,13 +208,13 @@ fn transform(i) {
|
||||
]
|
||||
}
|
||||
startSketchOn(XY)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> polygon({
|
||||
|> startProfile(at = [0, 0])
|
||||
|> polygon(
|
||||
radius = 10,
|
||||
numSides = 4,
|
||||
center = [0, 0],
|
||||
inscribed = false
|
||||
}, %)
|
||||
inscribed = false,
|
||||
)
|
||||
|> extrude(length = 4)
|
||||
|> patternTransform(instances = 3, transform = transform)
|
||||
```
|
||||
|
@ -10,9 +10,11 @@ Create a regular polygon with the specified number of sides that is either inscr
|
||||
|
||||
```js
|
||||
polygon(
|
||||
data: PolygonData,
|
||||
sketchSurfaceOrGroup: SketchOrSurface,
|
||||
tag?: TagDeclarator,
|
||||
radius: number,
|
||||
numSides: u64,
|
||||
center: [number],
|
||||
inscribed?: bool,
|
||||
): Sketch
|
||||
```
|
||||
|
||||
@ -21,9 +23,11 @@ polygon(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`PolygonData`](/docs/kcl/types/PolygonData) | Data for drawing a polygon | Yes |
|
||||
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | A sketch surface or a sketch. | Yes |
|
||||
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on | Yes |
|
||||
| `radius` | [`number`](/docs/kcl/types/number) | The radius of the polygon | Yes |
|
||||
| `numSides` | `u64` | The number of sides in the polygon | Yes |
|
||||
| `center` | [`[number]`](/docs/kcl/types/number) | The center point of the polygon | Yes |
|
||||
| `inscribed` | [`bool`](/docs/kcl/types/bool) | Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius | No |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -35,12 +39,12 @@ polygon(
|
||||
```js
|
||||
// Create a regular hexagon inscribed in a circle of radius 10
|
||||
hex = startSketchOn(XY)
|
||||
|> polygon({
|
||||
|> polygon(
|
||||
radius = 10,
|
||||
numSides = 6,
|
||||
center = [0, 0],
|
||||
inscribed = true
|
||||
}, %)
|
||||
inscribed = true,
|
||||
)
|
||||
|
||||
example = extrude(hex, length = 5)
|
||||
```
|
||||
@ -50,12 +54,12 @@ example = extrude(hex, length = 5)
|
||||
```js
|
||||
// Create a square circumscribed around a circle of radius 5
|
||||
square = startSketchOn(XY)
|
||||
|> polygon({
|
||||
|> polygon(
|
||||
radius = 5.0,
|
||||
numSides = 4,
|
||||
center = [10, 10],
|
||||
inscribed = false
|
||||
}, %)
|
||||
inscribed = false,
|
||||
)
|
||||
example = extrude(square, length = 5)
|
||||
```
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,8 +10,8 @@ Compute the number to a power.
|
||||
|
||||
```js
|
||||
pow(
|
||||
num: number,
|
||||
pow: number,
|
||||
input: number,
|
||||
exp: number,
|
||||
): number
|
||||
```
|
||||
|
||||
@ -24,8 +24,8 @@ pow(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `pow` | [`number`](/docs/kcl/types/number) | | Yes |
|
||||
| `input` | [`number`](/docs/kcl/types/number) | The number to raise. | Yes |
|
||||
| `exp` | [`number`](/docs/kcl/types/number) | The power to raise to. | Yes |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -36,8 +36,8 @@ pow(
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine(angle = 50, length = pow(5, 2))
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 50, length = pow(5, exp = 2))
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user