diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f4a45cb --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# From: https://docs.github.com/en/github/getting-started-with-github/configuring-git-to-handle-line-endings +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +.gitattributes text eol=lf +.gitignore text eol=lf +*.json text eol=lf +*.md text eol=lf +*.rs text eol=lf +*.sh text eol=lf +*.toml text eol=lf +*.yml text eol=lf diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..c4f6e2b --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: https://bevyengine.org/donate/ diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..1f40ebc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,54 @@ +--- +name: Bug Report +about: Report a bug to help us improve! +title: '' +labels: C-Bug, S-Needs-Triage +assignees: '' +--- + +## `disqualified` version + +The release number or commit hash of the version you're using. + +## Relevant system information + +This section is optional. Remove it if you know that the problem is not platform dependent. + +Rust version you're using: (`cargo --version`) + +```text + +``` + +> Notes: +> +> - Pay attention to the msrv (minimum supported rust version) of `disqualified`. +> - `nightly` should work, but sometimes there are regressions: please let us know! + +Operating system, including version: + +```text + +``` + +## What you did + +Describe how you arrived at the problem. If you can, consider providing a code snippet or link. + +## What went wrong + +If it's not clear, break this out into: + +- what were you expecting? +- what actually happened? + +## Additional information + +Other information that can be used to further reproduce or isolate the problem. +This commonly includes: + +- screenshots +- logs +- theories about what might be going wrong +- workarounds that you used +- links to related bugs, PRs or discussions diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..e8c0001 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,9 @@ +contact_links: + - name: Question + url: https://github.com/bevyengine/disqualified/discussions + about: Questions about how to use or contribute belong in Github Discussions. + You can use the search to check if someone already answered your question! + + - name: Community + url: https://discord.gg/bevy + about: If you'd like to converse with members of the `bevyengine` community, join us on discord. There is a channel for development of this crate. diff --git a/.github/ISSUE_TEMPLATE/docs_improvement.md b/.github/ISSUE_TEMPLATE/docs_improvement.md new file mode 100644 index 0000000..e318cb3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/docs_improvement.md @@ -0,0 +1,13 @@ +--- +name: Documentation Improvement +about: Help us write better documentation! +title: '' +labels: C-Documentation, S-Needs-Triage +assignees: '' +--- + +## How can the documentation be improved? + +Provide a link to the documentation and describe how it could be improved. In what ways is it incomplete, incorrect, or misleading? + +If you have suggestions on exactly what the new docs should say, feel free to include them here. Alternatively, make the changes yourself and create a pull request instead. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..0ac1873 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,24 @@ +--- +name: Feature Request +about: Propose a new feature! +title: '' +labels: C-Feature, S-Needs-Triage +assignees: '' +--- + +## What problem does this solve or what need does it fill? + +A description of why this particular feature should be added. + +## What solution would you like? + +The solution you propose for the problem presented. + +## What alternative(s) have you considered? + +Other solutions to solve and/or work around the problem presented. + +## Additional context + +Any other information you would like to add such as related previous work, +screenshots, benchmarks, etc. diff --git a/.github/ISSUE_TEMPLATE/performance_regression.md b/.github/ISSUE_TEMPLATE/performance_regression.md new file mode 100644 index 0000000..30871aa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/performance_regression.md @@ -0,0 +1,67 @@ +--- +name: Performance Regression +about: Running slowly after upgrading? Report a performance regression. +title: '' +labels: C-Bug, C-Performance, P-Regression, S-Needs-Triage +assignees: '' +--- + +## `disqualified` version + +Original: `` + +Current: `` + +## Relevant system information + +This section is optional. Remove it if you know that the problem is not platform dependent. + +Rust version you're using: (`cargo --version`) + +```text + +``` + +> Notes: +> +> - Pay attention to the msrv (minimum supported rust version) of `disqualified`. +> - `nightly` should work, but sometimes there are regressions: please let us know! + +Operating system, including version: + +```text + +``` + +## What's performing poorly? + +Describe how you arrived at the problem. If you can, consider providing a code snippet or link +to help reproduce the regression. + +If the exact scenario is not immediately reproducible on `cargo run`, please include a set list of steps to produce the correct setup. + +## Before and After Traces + +To best help us investigate the regression, it's best to provide as much detailed profiling +data as possible. + +If your app is running slowly, please show profiler traces before and after the change. +For more information on how to get these traces, see +. + +If this is about a compile-time regression, please provide the full output of `cargo build --timings`, +for more information see . + +- Before: +- After: + +## Additional information + +Other information that can be used to further reproduce or isolate the problem. +This commonly includes: + +- screenshots +- logs +- theories about what might be going wrong +- workarounds that you used +- links to related bugs, PRs or discussions diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..72fbf07 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: cargo + directory: / + schedule: + interval: weekly + labels: + - "C-Dependencies" + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + labels: + - "C-Dependencies" diff --git a/.github/example-run/short_name.ron b/.github/example-run/short_name.ron new file mode 100644 index 0000000..72873dd --- /dev/null +++ b/.github/example-run/short_name.ron @@ -0,0 +1,2 @@ +( +) diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml new file mode 100644 index 0000000..6976a23 --- /dev/null +++ b/.github/linters/.markdown-lint.yml @@ -0,0 +1,9 @@ +{ + "MD013": false, + "no-inline-html": { + "allowed_elements": [ + "details", + "summary" + ] + } +} \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..475c4f4 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,42 @@ +# Objective + +Describe the objective or issue this PR addresses. + +If you're fixing a specific issue, simply say "Fixes #X". + +## Solution + +Describe the solution used to achieve the objective above. + +## Testing + +- Did you test these changes? If so, how? +- Are there any parts that need more testing? +- How can other people (reviewers) test your changes? Is there anything specific they need to know? +- If relevant, what platforms did you test these changes on, and are there any important ones you can't test? + +## Showcase + +This section is optional. If this PR does not include a visual change or does not add a new feature, you can delete this section. + +- Help others understand the result of this PR by showcasing your awesome work! +- If this PR adds a new feature or public API, consider adding a brief pseudo-code snippet of it in action +- If this PR includes a visual change, consider adding a screenshot, GIF, or video + - If you want, you could even include a before/after comparison! +- If the Migration Guide adequately covers the changes, you can delete this section + +While a showcase should aim to be brief and digestible, you can use a toggleable section to save space on longer showcases: + +```rust +println!("My super cool code."); +``` + + + +## Migration Guide + +> This section is optional. If there are no breaking changes, you can delete this section. + +- If this PR is a breaking change (relative to the last release), describe how a user might need to migrate their code to support these changes +- Simply adding new functionality is not a breaking change. +- Fixing behavior that was definitely a bug, rather than a questionable design choice is not a breaking change. diff --git a/.github/workflows/action-on-PR-labeled.yml b/.github/workflows/action-on-PR-labeled.yml new file mode 100644 index 0000000..bf2d71e --- /dev/null +++ b/.github/workflows/action-on-PR-labeled.yml @@ -0,0 +1,30 @@ +name: Action on PR labeled + +# This workflow has write permissions on the repo +# It must not checkout a PR and run untrusted code + +on: + pull_request_target: + types: + - labeled + +permissions: + pull-requests: 'write' + +jobs: + comment-on-breaking-change-label: + runs-on: ubuntu-latest + if: github.event.label.name == 'M-Needs-Migration-Guide' && !contains(github.event.pull_request.body, '## Migration Guide') + steps: + - uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `It looks like your PR is a breaking change, but you didn't provide a migration guide. + + Could you add some context on what users should update when this change get released? + Putting it after a \`## Migration Guide\` will help it get automatically picked up by our tooling.` + }) diff --git a/.github/workflows/ci-comment-failures.yml b/.github/workflows/ci-comment-failures.yml new file mode 100644 index 0000000..65d6eda --- /dev/null +++ b/.github/workflows/ci-comment-failures.yml @@ -0,0 +1,164 @@ +name: CI - PR Comments + + # This workflow has write permissions on the repo + # It must not checkout a PR and run untrusted code + +# Also requesting write permissions on PR to be able to comment +permissions: + pull-requests: 'write' + +on: + workflow_run: + workflows: ["CI"] + types: + - completed + +jobs: + + missing-examples: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'failure' + steps: + - name: 'Download artifact' + id: find-artifact + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.event.workflow_run.id }}, + }); + var matchArtifacts = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "missing-examples" + }); + if (matchArtifacts.length == 0) { return "false" } + var matchArtifact = matchArtifacts[0]; + var download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + var fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/missing-examples.zip', Buffer.from(download.data)); + return "true" + - run: unzip missing-examples.zip + if: ${{ steps.find-artifact.outputs.result == 'true' }} + - name: 'Comment on PR' + if: ${{ steps.find-artifact.outputs.result == 'true' }} + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var fs = require('fs'); + var issue_number = Number(fs.readFileSync('./NR')); + if (fs.existsSync('./missing-metadata')) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue_number, + body: 'You added a new example but didn\'t add metadata for it. Please update the root Cargo.toml file.' + }); + } + + missing-features: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'failure' + steps: + - name: 'Download artifact' + id: find-artifact + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.event.workflow_run.id }}, + }); + var matchArtifacts = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "missing-features" + }); + if (matchArtifacts.length == 0) { return "false" } + var matchArtifact = matchArtifacts[0]; + var download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + var fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/missing-features.zip', Buffer.from(download.data)); + return "true" + - run: unzip missing-features.zip + if: ${{ steps.find-artifact.outputs.result == 'true' }} + - name: 'Comment on PR' + if: ${{ steps.find-artifact.outputs.result == 'true' }} + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var fs = require('fs'); + var issue_number = Number(fs.readFileSync('./NR')); + if (fs.existsSync('./missing-features')) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue_number, + body: 'You added a new feature but didn\'t add a description for it. Please update the root Cargo.toml file.' + }); + } + + msrv: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'failure' + steps: + - name: 'Download artifact' + id: find-artifact + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.event.workflow_run.id }}, + }); + var matchArtifacts = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "msrv" + }); + if (matchArtifacts.length == 0) { return "false" } + var matchArtifact = matchArtifacts[0]; + var download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + var fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/msrv.zip', Buffer.from(download.data)); + return "true" + - run: unzip msrv.zip + if: ${{ steps.find-artifact.outputs.result == 'true' }} + - name: 'Comment on PR' + if: ${{ steps.find-artifact.outputs.result == 'true' }} + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var fs = require('fs'); + var issue_number = Number(fs.readFileSync('./NR')); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue_number, + body: 'Your PR increases the Minimum Supported Rust Version (`msrv`). Please update the `rust-version` field in ``Cargo.toml.' + }); diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d0cef74 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,328 @@ +name: Continuous integration + +on: + merge_group: + pull_request: + push: + branches: + - main + - release-* + +env: + CARGO_TERM_COLOR: always + # If nightly is breaking CI, modify this variable to target a specific nightly version. + NIGHTLY_TOOLCHAIN: nightly + +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + +jobs: + build: + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-build-stable-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@stable + - name: Build & run tests + run: cargo test --workspace --lib --bins --tests --benches + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-C debuginfo=0 -D warnings" + + lint: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-ci-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + - name: Check formatting + run: cargo fmt --all -- --check + - name: Clippy + run: cargo clippy --workspace --all-targets --all-features -- -Dwarnings + + miri: + # Explicitly use macOS 14 to take advantage of M1 chip. + runs-on: macos-14 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-miri-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.NIGHTLY_TOOLCHAIN }} + components: miri + - name: CI job + run: cargo miri test + env: + RUSTFLAGS: -Zrandomize-layout + + check-compiles: + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: lint + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-check-compiles-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + - name: Check Compile + run: | + cargo test --target-dir ../../../target + cargo check --benches --target-dir ../target --manifest-path ./benches/Cargo.toml + cargo check --workspace --examples + cargo check --workspace + cargo check --workspace --tests + + check-compiles-no-std: + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: lint + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-check-compiles-no-std-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-unknown-none + - name: Check Compile + run: cargo check --no-default-features + + build-wasm: + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: build + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ubuntu-assets-cargo-build-wasm-stable-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@stable + with: + target: wasm32-unknown-unknown + - name: Check wasm + run: cargo check --target wasm32-unknown-unknown + + build-wasm-atomics: + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: build + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ubuntu-assets-cargo-build-wasm-nightly-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.NIGHTLY_TOOLCHAIN }} + targets: wasm32-unknown-unknown + components: rust-src + - name: Check wasm + run: cargo check --target wasm32-unknown-unknown -Z build-std=std,panic_abort + env: + RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory" + + markdownlint: + runs-on: ubuntu-latest + timeout-minutes: 30 + if: always() + steps: + - uses: actions/checkout@v4 + with: + # Full git history is needed to get a proper list of changed files within `super-linter` + fetch-depth: 0 + - name: Run Markdown Lint + uses: docker://ghcr.io/github/super-linter:slim-v4 + env: + MULTI_STATUS: false + VALIDATE_ALL_CODEBASE: false + VALIDATE_MARKDOWN: true + DEFAULT_BRANCH: main + + toml: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Install taplo + run: cargo install taplo-cli --locked + - name: Run Taplo + id: taplo + run: taplo fmt --check --diff + - name: Taplo info + if: failure() + run: | + echo 'To fix toml fmt, please run `taplo fmt`.' + echo 'To check for a diff, run `taplo fmt --check --diff`.' + echo 'You can find taplo here: https://taplo.tamasfe.dev/.' + echo 'Also use the `Even Better Toml` extension.' + echo 'You can find the extension here: https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml' + + typos: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: Check for typos + uses: crate-ci/typos@v1.27.3 + - name: Typos info + if: failure() + run: | + echo 'To fix typos, please run `typos -w`' + echo 'To check for a diff, run `typos`' + echo 'You can find typos here: https://crates.io/crates/typos' + echo 'if you use VSCode, you can also install `Typos Spell Checker' + echo 'You can find the extension here: https://marketplace.visualstudio.com/items?itemName=tekumara.typos-vscode' + + run-examples-macos-metal: + # Explicitly use macOS 14 to take advantage of M1 chip. + runs-on: macos-14 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Build + # this uses the same command as when running the example to ensure build is reused + run: | + CI_TESTING_CONFIG=.github/example-run/short_name.ron cargo build --example short_name + - name: Run examples + run: | + for example in .github/example-run/*.ron; do + example_name=`basename $example .ron` + echo -n $example_name > last_example_run + echo "running $example_name - "`date` + time CI_TESTING_CONFIG=$example cargo run --example $example_name + sleep 10 + done + + check-doc: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-check-doc-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.NIGHTLY_TOOLCHAIN }} + - name: Build doc + run: cargo doc --workspace --all-features --no-deps --document-private-items --keep-going + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-C debuginfo=0 --cfg docsrs_dep" + - name: Check doc + run: cargo test --workspace --doc + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-C debuginfo=0 --cfg docsrs_dep" + - name: Installs cargo-deadlinks + run: cargo install --force cargo-deadlinks + - name: Checks dead links + run: cargo deadlinks --dir target/documentation + continue-on-error: true + + msrv: + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: build + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-msrv-${{ hashFiles('**/Cargo.toml') }} + - name: Get minimum supported rust version + id: msrv + run: | + msrv=`cargo metadata --no-deps --format-version 1 | jq --raw-output '.packages[] | select(.name=="disqualified") | .rust_version'` + echo "msrv=$msrv" >> $GITHUB_OUTPUT + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ steps.msrv.outputs.msrv }} + - name: Run cargo check + id: check + run: | + echo 'If this fails, run `cargo msrv` and update the msrv in `Cargo.toml`.' + cargo check + - name: Save PR number + if: ${{ failure() && github.event_name == 'pull_request' && steps.check.conclusion == 'failure' }} + run: | + mkdir -p ./msrv + echo ${{ github.event.number }} > ./msrv/NR + - uses: actions/upload-artifact@v4 + if: ${{ failure() && github.event_name == 'pull_request' && steps.check.conclusion == 'failure' }} + with: + name: msrv + path: msrv/ diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml new file mode 100644 index 0000000..ceb0f42 --- /dev/null +++ b/.github/workflows/dependencies.yml @@ -0,0 +1,61 @@ +name: Dependencies + +on: + pull_request: + paths: + - '**/Cargo.toml' + - 'deny.toml' + push: + paths: + - '**/Cargo.toml' + - 'deny.toml' + branches: + - main + +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + +env: + CARGO_TERM_COLOR: always + +jobs: + check-advisories: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Install cargo-deny + run: cargo install cargo-deny + - name: Check for security advisories and unmaintained crates + run: cargo deny check advisories + + check-bans: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Install cargo-deny + run: cargo install cargo-deny + - name: Check for banned and duplicated dependencies + run: cargo deny check bans + + check-licenses: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Install cargo-deny + run: cargo install cargo-deny + - name: Check for unauthorized licenses + run: cargo deny check licenses + + check-sources: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Install cargo-deny + run: cargo install cargo-deny + - name: Checked for unauthorized crate sources + run: cargo deny check sources diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml new file mode 100644 index 0000000..f888fdc --- /dev/null +++ b/.github/workflows/post-release.yml @@ -0,0 +1,56 @@ +name: Post-release version bump + +# how to trigger: https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow +on: + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + ci: + if: github.repository == 'bevyengine/disqualified' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install cargo-release + run: cargo install cargo-release + + - name: Setup post-release version bump + run: | + # Set the commit author to the github-actions bot. See discussion here for more information: + # https://github.com/actions/checkout/issues/13#issuecomment-724415212 + # https://github.community/t/github-actions-bot-email-address/17204/6 + git config user.name 'Auto Releaser' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + # Read the current version from Cargo.toml + current_version=$(cargo metadata --format-version 1 --no-deps | \ + jq --raw-output '.packages | .[] | select(.name == "disqualified").version') + # Sanity check: current version should be 0.X.Y-dev + if ! grep -q '^0\.[0-9]\+\.[0-9]\+-dev$' <<< "${current_version}"; then + echo "Invalid version (not in 0.X.Y-dev format): ${current_version}" + exit 1 + fi + minor_version=$(sed 's/^0\.\([0-9]\+\).*/\1/' <<< "${current_version}") + next_version=0.$((minor_version + 1)).0-dev + echo "Bumping version to ${next_version}" + # See release.yml for meaning of these arguments + cargo release "${next_version}" \ + --workspace \ + --no-publish \ + --execute \ + --no-tag \ + --no-confirm \ + --no-push \ + --exclude errors \ + + - name: Create PR + uses: peter-evans/create-pull-request@v7 + with: + delete-branch: true + base: "main" + title: "Bump Version after Release" + body: | + Bump version after release + This PR has been auto-generated diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8b907c1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,53 @@ +name: Release + +# how to trigger: https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow +on: + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + ci: + if: github.repository == 'bevyengine/disqualified' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install cargo-release + run: cargo install cargo-release + + - name: Setup release + run: | + # Set the commit author to the github-actions bot. See discussion here for more information: + # https://github.com/actions/checkout/issues/13#issuecomment-724415212 + # https://github.community/t/github-actions-bot-email-address/17204/6 + git config user.name 'Auto Releaser' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + # release: remove the dev suffix, like going from 0.X.0-dev to 0.X.0 + # --workspace: updating all crates in the workspace + # --no-publish: do not publish to crates.io + # --execute: not a dry run + # --no-tag: do not push tag for each new version + # --no-push: do not push the update commits + # --dependent-version upgrade: change 0.X.0-dev in internal dependencies to 0.X.0 + # --exclude: ignore those packages + cargo release release \ + --workspace \ + --no-publish \ + --execute \ + --no-tag \ + --no-confirm \ + --no-push \ + --dependent-version upgrade \ + --exclude ci \ + --exclude errors \ + + - name: Create PR + uses: peter-evans/create-pull-request@v7 + with: + delete-branch: true + base: "main" + title: "Preparing Next Release" + body: | + Preparing next release. This PR has been auto-generated. diff --git a/.github/workflows/validation-jobs.yml b/.github/workflows/validation-jobs.yml new file mode 100644 index 0000000..d8c4938 --- /dev/null +++ b/.github/workflows/validation-jobs.yml @@ -0,0 +1,222 @@ +name: validation jobs + +on: + merge_group: + pull_request: + push: + branches: + - main + - release-* + +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + +env: + CARGO_TERM_COLOR: always + # If nightly is breaking CI, modify this variable to target a specific nightly version. + NIGHTLY_TOOLCHAIN: nightly + +jobs: + build-and-install-on-iOS: + if: ${{ github.event_name == 'merge_group' }} + runs-on: macos-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: actions/cache@v4 + with: + path: | + target + key: ${{ runner.os }}-ios-install-${{ hashFiles('**/Cargo.lock') }} + # TODO: remove x86 target once it always run on arm GitHub runners + - name: Add iOS targets + run: rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim + - name: Build and install iOS app in iOS Simulator. + run: cd examples/mobile && make install + + build-android: + if: ${{ github.event_name == 'merge_group' }} + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-build-android-${{ hashFiles('**/Cargo.toml') }} + + run-examples-linux: + # also run when pushed to main to update reference screenshots + if: ${{ github.event_name != 'pull_request' }} + runs-on: ubuntu-22.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: Build + # this uses the same command as when running the example to ensure build is reused + run: | + CI_TESTING_CONFIG=.github/example-run/short_name.ron cargo build --example short_name + - name: Run examples + run: | + for example in .github/example-run/*.ron; do + example_name=`basename $example .ron` + echo -n $example_name > last_example_run + echo "running $example_name - "`date` + time CI_TESTING_CONFIG=$example cargo run --example $example_name + sleep 10 + done + - uses: actions/upload-artifact@v4 + if: ${{ failure() && github.event_name == 'pull_request' }} + with: + name: example-run-linux + path: example-run/ + + run-examples-on-windows-dx12: + if: ${{ github.event_name != 'pull_request' }} + runs-on: windows-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Build + shell: bash + # this uses the same command as when running the example to ensure build is reused + run: | + CI_TESTING_CONFIG=.github/example-run/short_name.ron cargo build --example short_name + - name: Run examples + shell: bash + run: | + for example in .github/example-run/*.ron; do + example_name=`basename $example .ron` + echo -n $example_name > last_example_run + echo "running $example_name - "`date` + time CI_TESTING_CONFIG=$example cargo run --example $example_name + sleep 10 + done + - uses: actions/upload-artifact@v4 + if: ${{ failure() && github.event_name == 'pull_request' }} + with: + name: example-run-windows + path: example-run/ + + run-examples-on-wasm: + if: ${{ github.event_name == 'merge_group' }} + runs-on: ubuntu-22.04 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@stable + with: + target: wasm32-unknown-unknown + + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ~/.github/start-wasm-example/node_modules + target/ + key: ${{ runner.os }}-wasm-run-examples-${{ hashFiles('**/Cargo.toml') }} + + - name: install xvfb, llvmpipe and lavapipe + run: | + sudo apt-get update -y -qq + sudo add-apt-repository ppa:kisak/turtle -y + sudo apt-get update + sudo apt install -y xvfb libegl1-mesa libgl1-mesa-dri libxcb-xfixes0-dev mesa-vulkan-drivers + + - name: Install wasm-bindgen + run: cargo install --force wasm-bindgen-cli + + - name: Setup playwright + run: | + cd .github/start-wasm-example + npm install + npx playwright install --with-deps + cd ../.. + + - name: First Wasm build + run: | + cargo build --release --example testbed_ui --target wasm32-unknown-unknown + + - name: Run examples + shell: bash + run: | + # start a webserver + python3 -m http.server --directory examples/wasm & + + xvfb-run cargo run -p build-wasm-example -- --browsers chromium --browsers firefox --frames 25 --test 2d_shapes lighting text_debug breakout + + - name: Save screenshots + uses: actions/upload-artifact@v4 + with: + name: screenshots-wasm + path: .github/start-wasm-example/screenshot-*.png + + build-without-default-features: + if: ${{ github.event_name == 'merge_group' }} + timeout-minutes: 30 + strategy: + max-parallel: 1 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Build + run: cargo build --no-default-features + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-C debuginfo=0 -D warnings" + + build-without-default-features-status: + if: | + always() && + github.event_name == 'merge_group' + needs: build-without-default-features + runs-on: ubuntu-latest + steps: + - name: Successful + if: ${{ !(contains(needs.*.result, 'failure')) }} + run: exit 0 + - name: Failing + if: ${{ contains(needs.*.result, 'failure') }} + run: exit 1 + + check-unused-dependencies: + if: ${{ github.event_name == 'merge_group' }} + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-check-unused-dependencies-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.NIGHTLY_TOOLCHAIN }} + - name: Installs cargo-udeps + run: cargo install --force cargo-udeps + - name: Run cargo udeps + run: cargo udeps diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml new file mode 100644 index 0000000..cf8ff1a --- /dev/null +++ b/.github/workflows/weekly.yml @@ -0,0 +1,111 @@ +name: Weekly beta compile test + +on: + schedule: + # New versions of rust release on Thursdays. We test on Mondays to get at least 3 days of warning before all our CI breaks again. + # https://forge.rust-lang.org/release/process.html#release-day-thursday + - cron: '0 12 * * 1' + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + test: + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@beta + - name: Install Linux dependencies + run: cargo test --workspace --lib --bins --tests --benches + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-C debuginfo=0 -D warnings" + + lint: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@beta + with: + components: rustfmt, clippy + - name: Check formatting + run: cargo fmt --all -- --check + - name: Clippy + run: cargo clippy --workspace --all-targets --all-features -- -Dwarnings + + check-compiles: + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: test + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-check-compiles-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + - name: Check Compile + run: | + cargo test --target-dir ../../../target + cargo check --benches --target-dir ../target --manifest-path ./benches/Cargo.toml + cargo check --workspace --examples + cargo check --workspace + cargo check --workspace --tests + + check-doc: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@beta + - name: Build and check docs + run: cargo run -p ci -- doc + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-C debuginfo=0 --cfg docsrs_dep" + + open-issue: + name: Warn that weekly CI fails + runs-on: ubuntu-latest + needs: [test, lint, check-compiles, check-doc] + permissions: + issues: write + # Use always() so the job doesn't get canceled if any other jobs fail + if: ${{ always() && contains(needs.*.result, 'failure') }} + steps: + - name: Create issue + run: | + previous_issue_number=$(gh issue list \ + --search "$TITLE in:title" \ + --json number \ + --jq '.[0].number') + if [[ -n $previous_issue_number ]]; then + gh issue comment $previous_issue_number \ + --body "Weekly pipeline still fails: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + else + gh issue create \ + --title "$TITLE" \ + --label "$LABELS" \ + --body "$BODY" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + TITLE: Main branch fails to compile on Rust beta. + LABELS: C-Bug,S-Needs-Triage + BODY: | + ## Weekly CI run has failed. + [The offending run.](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml new file mode 100644 index 0000000..96a2879 --- /dev/null +++ b/.github/workflows/welcome.yml @@ -0,0 +1,47 @@ +name: Welcome new contributors + +# This workflow has write permissions on the repo +# It must not checkout a PR and run untrusted code + +on: + pull_request_target: + types: + - opened + +jobs: + welcome: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/github-script@v7 + with: + script: | + // Get a list of all issues created by the PR opener + // See: https://octokit.github.io/rest.js/#pagination + const creator = context.payload.sender.login + const opts = github.rest.issues.listForRepo.endpoint.merge({ + ...context.issue, + creator, + state: 'all' + }) + const issues = await github.paginate(opts) + + for (const issue of issues) { + if (issue.number === context.issue.number) { + continue + } + + if (issue.pull_request) { + return // Creator is already a contributor. + } + } + + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `**Welcome**, new contributor! + + Please make sure you've read our [contributing guide](https://bevyengine.org/learn/contribute/introduction) and we look forward to reviewing your pull request shortly ✨` + }) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6919713 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Rust build artifacts +/target +crates/*/target +**/*.rs.bk +/benches/target +/tools/compile_fail_utils/target + +# Cargo +Cargo.lock +.cargo/config +.cargo/config.toml + +# IDE files +/.idea +/.vscode +.zed +dxcompiler.dll +dxil.dll diff --git a/Cargo.lock b/Cargo.lock index 9f92d05..9f70eee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,711 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "benches" +version = "0.0.0" +dependencies = [ + "criterion", + "rand", + "rand_chacha", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + +[[package]] +name = "criterion" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "csv" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "disqualified" version = "1.0.0" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "errors" +version = "0.0.0" +dependencies = [ + "disqualified", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.214" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.214" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index e4dcf55..d5c144d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,14 +3,55 @@ name = "disqualified" version = "1.0.0" edition = "2021" description = "Make rust type names more user-readable" -# homepage = "https://bevyengine.org" +homepage = "https://github.com/bevyengine/disqualified" repository = "https://github.com/bevyengine/disqualified" license = "MIT OR Apache-2.0" keywords = ["bevy", "type", "name", "short", "log"] -rust-version = "1.65.0" +rust-version = "1.75.0" [features] default = ["alloc"] alloc = [] [dependencies] + +[lib] + +[workspace] +exclude = ["benches", "compile_fail", "tools/compile_fail_utils"] +members = ["errors", ".", "benches"] + +[workspace.lints.clippy] +doc_markdown = "warn" +manual_let_else = "warn" +match_same_arms = "warn" +redundant_closure_for_method_calls = "warn" +redundant_else = "warn" +semicolon_if_nothing_returned = "warn" +undocumented_unsafe_blocks = "warn" +unwrap_or_default = "warn" +ptr_as_ptr = "warn" +ptr_cast_constness = "warn" +ref_as_ptr = "warn" +std_instead_of_core = "warn" +std_instead_of_alloc = "warn" +alloc_instead_of_core = "warn" + +[workspace.lints.rust] +missing_docs = "warn" +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(docsrs_dep)'] } +unsafe_code = "deny" +unsafe_op_in_unsafe_fn = "warn" +unused_qualifications = "warn" + +# Examples + +[[example]] +name = "short_name" +path = "examples/demonstrations/short_name.rs" +doc-scrape-examples = true + +[package.metadata.example.short_name] +name = "short_name" +description = "Demonstrates the functionality of `short_name`." +category = "Demonstration" diff --git a/benches/Cargo.toml b/benches/Cargo.toml new file mode 100644 index 0000000..9a61f2b --- /dev/null +++ b/benches/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "benches" +edition = "2021" +description = "Benchmarks that test performance" +publish = false +license = "MIT OR Apache-2.0" + +[dev-dependencies] +rand = "0.8" +rand_chacha = "0.3" +criterion = { version = "0.3", features = ["html_reports"] } + +[profile.release] +opt-level = 3 +lto = true + +[[bench]] +name = "dummy" +path = "benches/dummy.rs" +harness = false diff --git a/benches/README.md b/benches/README.md new file mode 100644 index 0000000..216e7cd --- /dev/null +++ b/benches/README.md @@ -0,0 +1,28 @@ +# Benchmarks + +This is a crate with a collection of benchmarks, separate from the rest of the crates. + +## Running the benchmarks + +1. Setup everything you need to develop in rust. +2. `cd` into the `benches` directory (where this README is located). + + ```sh + disqualified $ cd benches + ``` + +3. Run the benchmarks with cargo (This will take a while) + + ```sh + disqualified/benches $ cargo bench + ``` + + If you'd like to only compile the benchmarks (without running them), you can do that like this: + + ```sh + disqualified/benches $ cargo bench --no-run + ``` + +## Criterion + +The benchmarks use [Criterion](https://crates.io/crates/criterion). If you want to learn more about using Criterion for comparing performance against a baseline or generating detailed reports, you can read the [Criterion.rs documentation](https://bheisler.github.io/criterion.rs/book/criterion_rs.html). diff --git a/benches/benches/dummy.rs b/benches/benches/dummy.rs new file mode 100644 index 0000000..caca1f6 --- /dev/null +++ b/benches/benches/dummy.rs @@ -0,0 +1,14 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; + +fn foo(c: &mut Criterion) { + c.bench_function("foo_1000", |b| { + b.iter(|| { + (0..1000).for_each(|test_case| { + black_box(black_box(test_case * 2) * black_box(test_case * 2)); + }) + }); + }); +} + +criterion_group!(benches, foo); +criterion_main!(benches); diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..1d72763 --- /dev/null +++ b/deny.toml @@ -0,0 +1,82 @@ +[graph] +all-features = true + +[advisories] +version = 2 +ignore = [] + +[licenses] +version = 2 +allow = [ + "0BSD", + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "BSL-1.0", + "CC0-1.0", + "ISC", + "MIT", + "MIT-0", + "Unlicense", + "Zlib", +] + +exceptions = [ + { name = "unicode-ident", allow = [ + "Unicode-DFS-2016", + ] }, + { name = "symphonia", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-bundle-flac", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-bundle-mp3", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-codec-aac", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-codec-adpcm", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-codec-pcm", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-codec-vorbis", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-core", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-format-isomp4", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-format-riff", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-metadata", allow = [ + "MPL-2.0", + ] }, + { name = "symphonia-utils-xiph", allow = [ + "MPL-2.0", + ] }, +] + +[bans] +multiple-versions = "warn" +wildcards = "deny" +# Certain crates that we don't want multiple versions of in the dependency tree +deny = [ + { name = "ahash", deny-multiple-versions = true }, + { name = "android-activity", deny-multiple-versions = true }, + { name = "glam", deny-multiple-versions = true }, + { name = "raw-window-handle", deny-multiple-versions = true }, +] + +[sources] +unknown-registry = "deny" +unknown-git = "deny" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] diff --git a/documentation/debugging.md b/documentation/debugging.md new file mode 100644 index 0000000..a704a9d --- /dev/null +++ b/documentation/debugging.md @@ -0,0 +1,8 @@ +# Debugging + +## Macro Debugging + +- Print the final output of a macro using `cargo rustc --profile=check -- -Zunstable-options --pretty=expanded` + - Alternatively you could install and use [cargo expand](https://github.com/dtolnay/cargo-expand) which adds syntax highlighting to the terminal output. + - Additionally get pager by piping to `less` ( on Unix systems ): `cargo expand --color always | less -R` +- Print output during macro compilation using `eprintln!("hi");` diff --git a/documentation/linters.md b/documentation/linters.md new file mode 100644 index 0000000..d53a4c5 --- /dev/null +++ b/documentation/linters.md @@ -0,0 +1,47 @@ +# Linters in this Repository + +## Code Format Linting with [rustfmt](https://github.com/rust-lang/rustfmt) + +Can be automatically validated with [`cargo run -p ci`](../tools/ci) (which also runs other checks). Running this command will actually format the code: + +```bash +cargo fmt --all +``` + +## Code Linting with [Clippy](https://github.com/rust-lang/rust-clippy) + +Can be automatically run with [`cargo run -p ci`](../tools/ci) (which also runs other checks) or manually with this command: + +```bash +cargo clippy --workspace --all-targets --all-features -- -D warnings +``` + +Explanation: + +* `-D warnings`: No warnings are allowed in the codebase. + +## [super-linter](https://github.com/github/super-linter) + +`super-linter` provides easy access to many different Linters. + +### [markdownlint](https://github.com/DavidAnson/markdownlint) + +`markdownlint` is provided by `super-linter` and is responsible for `.md` files. +Its configuration is saved in the [.markdown-lint.yml](../.github/linters/.markdown-lint.yml) file. + +The provided rules are documented [here](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md) and information about setting the config can be seen [here](https://github.com/DavidAnson/markdownlint#optionsconfig). + +#### Using [VS Code markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) + +If you want to use the VS Code Extension with the rules defined in [.markdown-lint.yml](../.github/linters/.markdown-lint.yml), then you need to create a local config file in the root of the project with the configuration below. +Currently, this is not needed as the extension already disables the rule `MD013` by default. + +```json +{ + "extends": ".github/linters/.markdown-lint.yml" +} +``` + +### Other Linters provided by [super-linter](https://github.com/github/super-linter) + +All other linters not mentioned in the this file are not activated and can be seen [here](https://github.com/github/super-linter#supported-linters). diff --git a/errors/Cargo.toml b/errors/Cargo.toml new file mode 100644 index 0000000..be63f4e --- /dev/null +++ b/errors/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "errors" +edition = "2021" +description = "Documentation and tests for error codes" +publish = false +license = "MIT OR Apache-2.0" + +[dependencies] +disqualified = { path = ".." } + +[lints] +workspace = true diff --git a/errors/README.md b/errors/README.md new file mode 100644 index 0000000..735c5aa --- /dev/null +++ b/errors/README.md @@ -0,0 +1,3 @@ +# Error Codes + +This crate lists and tests explanations and examples of the error codes. diff --git a/errors/T0001.md b/errors/T0001.md new file mode 100644 index 0000000..5643bfc --- /dev/null +++ b/errors/T0001.md @@ -0,0 +1,3 @@ +# T0001 + +Placeholder diff --git a/errors/src/lib.rs b/errors/src/lib.rs new file mode 100644 index 0000000..7efad68 --- /dev/null +++ b/errors/src/lib.rs @@ -0,0 +1,4 @@ +//! Definitions of `disqualified`'s error codes that might occur at runtime. + +#[doc = include_str!("../T0001.md")] +pub struct T0001; diff --git a/examples/demonstrations/short_name.rs b/examples/demonstrations/short_name.rs new file mode 100644 index 0000000..157b5e1 --- /dev/null +++ b/examples/demonstrations/short_name.rs @@ -0,0 +1,4 @@ +use disqualified::*; + +fn main() { +} diff --git a/tools/compile_fail_utils/Cargo.toml b/tools/compile_fail_utils/Cargo.toml new file mode 100644 index 0000000..a3c20c0 --- /dev/null +++ b/tools/compile_fail_utils/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "compile_fail_utils" +edition = "2021" +description = "Utilities for compile tests" +homepage = "https://github.com/bevyengine/disqualified" +repository = "https://github.com/bevyengine/disqualified" +license = "MIT OR Apache-2.0" +publish = false + +[dependencies] +ui_test = "0.23.0" + +[[test]] +name = "example" +harness = false diff --git a/tools/compile_fail_utils/README.md b/tools/compile_fail_utils/README.md new file mode 100644 index 0000000..affc7e7 --- /dev/null +++ b/tools/compile_fail_utils/README.md @@ -0,0 +1,30 @@ +# Helpers for compile fail tests + +This crate contains everything needed to set up compile tests for this repository. It, like all compile test crates, is excluded from the workspace. This is done to not fail [`crater` tests](https://github.com/rust-lang/crater). The `CI` workflow executes these tests on the stable rust toolchain see ([tools/ci](../../tools/ci/src/main.rs)). + +## Writing new test cases + +Test cases are annotated .rs files. These annotations define how the test case should be run and what we're expecting to fail. Please see for more information. + +Annotations can roughly be split into global annotations which are prefixed with `//@` and define how tests should be run and error annotations which are prefixed with `//~` and define where errors we expect to happen. From the global annotations, you're only likely to care about `//@check-pass` which will make any compile errors in the test trigger a test failure. + +The error annotations are composed of two parts. +An optional location specifier: + +- `^` The error happens on the line above. +- `v` The error happens on the line below. +- `|` The error annotation is connected to another one. +- If the location specifier is missing, the error is assumed to happen on the same line as the annotation. + +An error matcher: + +- `E####` The error we're expecting has the [`####` rustc error code](https://doc.rust-lang.org/error_codes/error-index.html), e.g `E0499` +- `` The given [compiler lint](https://doc.rust-lang.org/rustc/lints/index.html) is triggered, e.g. `dead_code` +- `LEVEL: ` A compiler error of the given level (valid levels are: `ERROR`, `HELP`, `WARN` or `NOTE`) will be raised and it will contain the `substring`. Substrings can contain spaces. +- `LEVEL: //` Same as above but a regex is used to match the error message. + +An example of an error annotation would be `//~v ERROR: missing trait`. This error annotation will match any error occurring on the line below that contains the substring `missing trait`. + +## A note about `.stderr` files + +We're capable of generating `.stderr` files for all our compile tests. These files contain the error output generated by the test. To create or regenerate them yourself, trigger the tests with the `BLESS` environment variable set to any value (e.g. `BLESS="some symbolic value"`). We currently have to ignore mismatches between these files and the actual stderr output from their corresponding test due to issues with file paths. We attempt to sanitize file paths but for proc-macros, the compiler error messages contain file paths to the current toolchain's copy of the standard library. If we knew of a way to construct a path to the current toolchains folder we could fix this. diff --git a/tools/compile_fail_utils/src/lib.rs b/tools/compile_fail_utils/src/lib.rs new file mode 100644 index 0000000..e3dc202 --- /dev/null +++ b/tools/compile_fail_utils/src/lib.rs @@ -0,0 +1,133 @@ +use std::{ + env, + path::{Path, PathBuf}, +}; + +// Re-export ui_test so all the tests use the same version. +pub use ui_test; + +use ui_test::{ + color_eyre::eyre::eyre, + default_file_filter, default_per_file_config, + dependencies::DependencyBuilder, + run_tests_generic, + spanned::Spanned, + status_emitter::{Gha, StatusEmitter, Text}, + Args, Config, OutputConflictHandling, +}; + +/// Use this instead of hand rolling configs. +/// +/// `root_dir` is the directory your tests are contained in. Needs to be a path from crate root. +/// This config will build dependencies and will assume that the cargo manifest is placed at the +/// current working directory. +fn basic_config(root_dir: impl Into, args: &Args) -> ui_test::Result { + let root_dir = root_dir.into(); + + match root_dir.try_exists() { + Ok(true) => { /* success */ } + Ok(false) => { + return Err(eyre!("path does not exist: {:?}", root_dir)); + } + Err(error) => { + return Err(eyre!("failed to read path: {:?} ({:?})", root_dir, error)); + } + } + + let mut config = Config { + bless_command: Some( + "`cargo test` with the BLESS environment variable set to any non empty value" + .to_string(), + ), + output_conflict_handling: if env::var_os("BLESS").is_some() { + OutputConflictHandling::Bless + } else { + // stderr output changes between rust versions so we just rely on annotations + OutputConflictHandling::Ignore + }, + ..Config::rustc(root_dir) + }; + + config.with_args(args); + + let crate_root = ".."; + + // Don't leak contributor filesystem paths + config.path_stderr_filter(Path::new(crate_root), b"$CRATE_ROOT"); + config.path_stderr_filter(Path::new(env!("RUSTUP_HOME")), b"$RUSTUP_HOME"); + + // ui_test doesn't compile regex with perl character classes. + // \pL = unicode class for letters, \pN = unicode class for numbers + config.stderr_filter(r"\/home\/[\pL\pN_@#\-\. ]+", "$HOME"); + // Paths in .stderr seem to always be normalized to use /. Handle both anyway. + config.stderr_filter( + r"[a-zA-Z]:(?:\\|\/)users(?:\\|\/)[\pL\pN_@#\-\. ]+", // NOTE: [\pL\pN_@#\-\. ] is a poor attempt at handling usernames + "$HOME", + ); + + // Manually insert @aux-build: comments into test files. This needs to + // be done to build and link dependencies. Dependencies will be pulled from a + // Cargo.toml file. + config.comment_defaults.base().custom.insert( + "dependencies", + Spanned::dummy(vec![Box::new(DependencyBuilder::default())]), + ); + + Ok(config) +} + +/// Runs ui tests for a single directory. +/// +/// `root_dir` is the directory your tests are contained in. Needs to be a path from crate root. +pub fn test(test_name: impl Into, test_root: impl Into) -> ui_test::Result<()> { + test_multiple(test_name, [test_root]) +} + +/// Run ui tests with the given config +pub fn test_with_config(test_name: impl Into, config: Config) -> ui_test::Result<()> { + test_with_multiple_configs(test_name, [Ok(config)]) +} + +/// Runs ui tests for a multiple directories. +/// +/// `root_dirs` paths need to come from crate root. +pub fn test_multiple( + test_name: impl Into, + test_roots: impl IntoIterator>, +) -> ui_test::Result<()> { + let args = Args::test()?; + + let configs = test_roots.into_iter().map(|root| basic_config(root, &args)); + + test_with_multiple_configs(test_name, configs) +} + +/// Run ui test with the given configs. +/// +/// Tests for configs are run in parallel. +pub fn test_with_multiple_configs( + test_name: impl Into, + configs: impl IntoIterator>, +) -> ui_test::Result<()> { + let configs = configs + .into_iter() + .collect::>>()?; + + let emitter: Box = if env::var_os("CI").is_some() { + Box::new(( + Text::verbose(), + Gha:: { + name: test_name.into(), + }, + )) + } else { + Box::new(Text::quiet()) + }; + + run_tests_generic( + configs, + default_file_filter, + default_per_file_config, + emitter, + ) +} diff --git a/tools/compile_fail_utils/tests/example.rs b/tools/compile_fail_utils/tests/example.rs new file mode 100644 index 0000000..e409969 --- /dev/null +++ b/tools/compile_fail_utils/tests/example.rs @@ -0,0 +1,10 @@ +fn main() -> compile_test_utils::ui_test::Result<()> { + // Run all tests in the tests/example_tests folder. + // If we had more tests we could either call this function + // on every single one or use test_multiple and past it an array + // of paths. + // + // Don't forget that when running tests the working directory + // is set to the crate root. + compile_test_utils::test("tests/example_tests") +} diff --git a/tools/compile_fail_utils/tests/example_tests/basic_test.rs b/tools/compile_fail_utils/tests/example_tests/basic_test.rs new file mode 100644 index 0000000..4956de6 --- /dev/null +++ b/tools/compile_fail_utils/tests/example_tests/basic_test.rs @@ -0,0 +1,25 @@ +//! A basic example of a compilation failure test. +//! Use this as a template or for help with syntax. + +// Compiler warnings also need to be annotated. +#![allow(unused_variables, reason = "The variables are for basic demonstration purposes and don't need to be used.")] + +fn bad_moves() { + let x = String::new(); + // Help diagnostics need to be annotated + let y = x; + //~^ HELP: consider cloning + + // We expect a failure on this line + println!("{x}"); //~ ERROR: borrow + + + let x = String::new(); + // We expect the help message to mention cloning. + //~v HELP: consider cloning + let y = x; + + // Check error message using a regex + println!("{x}"); + //~^ ERROR: /(move)|(borrow)/ +} diff --git a/tools/compile_fail_utils/tests/example_tests/basic_test.stderr b/tools/compile_fail_utils/tests/example_tests/basic_test.stderr new file mode 100644 index 0000000..5fbd423 --- /dev/null +++ b/tools/compile_fail_utils/tests/example_tests/basic_test.stderr @@ -0,0 +1,39 @@ +error[E0382]: borrow of moved value: `x` + --> tests/example_tests/basic_test.rs:13:15 + | +7 | let x = String::new(); + | - move occurs because `x` has type `String`, which does not implement the `Copy` trait +8 | // Help diagnostics need to be annotated +9 | let y = x; + | - value moved here +... +13 | println!("{x}"); + | ^^^ value borrowed here after move + | + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider cloning the value if the performance cost is acceptable + | +9 | let y = x.clone(); + | ++++++++ + +error[E0382]: borrow of moved value: `x` + --> tests/example_tests/basic_test.rs:22:15 + | +16 | let x = String::new(); + | - move occurs because `x` has type `String`, which does not implement the `Copy` trait +... +19 | let y = x; + | - value moved here +... +22 | println!("{x}"); + | ^^^ value borrowed here after move + | + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider cloning the value if the performance cost is acceptable + | +19 | let y = x.clone(); + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/tools/compile_fail_utils/tests/example_tests/import.rs b/tools/compile_fail_utils/tests/example_tests/import.rs new file mode 100644 index 0000000..2d2364b --- /dev/null +++ b/tools/compile_fail_utils/tests/example_tests/import.rs @@ -0,0 +1,7 @@ +// You can import anything defined in the dependencies table of the crate. +use ui_test::Config; + +fn wrong_type() { + let _ = Config::this_function_does_not_exist(); + //~^ E0599 +} diff --git a/tools/compile_fail_utils/tests/example_tests/import.stderr b/tools/compile_fail_utils/tests/example_tests/import.stderr new file mode 100644 index 0000000..c0d36fb --- /dev/null +++ b/tools/compile_fail_utils/tests/example_tests/import.stderr @@ -0,0 +1,20 @@ +error[E0599]: no function or associated item named `this_function_does_not_exist` found for struct `Config` in the current scope + --> tests/example_tests/import.rs:5:21 + | +5 | let _ = Config::this_function_does_not_exist(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `Config` + | +note: if you're trying to build a new `Config` consider using one of the following associated functions: + Config::rustc + Config::cargo + --> $RUSTUP_HOME/.cargo/git/checkouts/ui_test-2b82183a391bb05c/680bb08/src/config.rs:63:5 + | +63 | pub fn rustc(root_dir: impl Into) -> Self { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +108 | pub fn cargo(root_dir: impl Into) -> Self { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tools/compile_fail_utils/tests/example_tests/pass_test.rs b/tools/compile_fail_utils/tests/example_tests/pass_test.rs new file mode 100644 index 0000000..6216492 --- /dev/null +++ b/tools/compile_fail_utils/tests/example_tests/pass_test.rs @@ -0,0 +1,10 @@ +//@check-pass + +// This code is expected to compile correctly. +fn correct_borrowing() { + let x = String::new(); + let y = &x; + + println!("{x}"); + println!("{y}"); +} diff --git a/tools/compile_fail_utils/tests/example_tests/pass_test.stderr b/tools/compile_fail_utils/tests/example_tests/pass_test.stderr new file mode 100644 index 0000000..975c7d2 --- /dev/null +++ b/tools/compile_fail_utils/tests/example_tests/pass_test.stderr @@ -0,0 +1,10 @@ +warning: function `correct_borrowing` is never used + --> tests/example_tests/pass_test.rs:4:4 + | +4 | fn correct_borrowing() { + | ^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(dead_code)]` on by default + +warning: 1 warning emitted + diff --git a/tools/publish.sh b/tools/publish.sh new file mode 100644 index 0000000..c30ca2f --- /dev/null +++ b/tools/publish.sh @@ -0,0 +1,29 @@ +# if crate A depends on crate B, B must come before A in this list +crates=( +) + +if [ -n "$(git status --porcelain)" ]; then + echo "You have local changes!" + exit 1 +fi + +pushd crates + +for crate in "${crates[@]}"; do + echo "Publishing ${crate}" + cp ../LICENSE-MIT "$crate" + cp ../LICENSE-APACHE "$crate" + pushd "$crate" + git add LICENSE-MIT LICENSE-APACHE + cargo publish --no-verify --allow-dirty + popd + sleep 20 +done + +popd + +echo "Publishing root crate" +cargo publish --allow-dirty + +echo "Cleaning local state" +git reset HEAD --hard diff --git a/typos.toml b/typos.toml new file mode 100644 index 0000000..af621e3 --- /dev/null +++ b/typos.toml @@ -0,0 +1,22 @@ +[files] +extend-exclude = [ + "*.patch", # Automatically generated files that should not be manually modified. + "*.bin", # Binary files + ".git/", # Version control files +] +ignore-hidden = false + +# Corrections take the form of a key/value pair. The key is the incorrect word +# and the value is the correct word. If the key and value are the same, the +# word is treated as always correct. If the value is an empty string, the word +# is treated as always incorrect. + +# Match Whole Word - Case Sensitive +[default.extend-identifiers] + +# Match Inside a Word - Case Insensitive +[default.extend-words] + +[default] +locale = "en-us" +extend-ignore-identifiers-re = []