This PR is easiest to review commit by commit.

Followup on https://github.com/bevyengine/bevy/pull/1309#issuecomment-767310084

- [x] Switch from a bash script to an xtask rust workspace member.
  - Results in ~30s longer CI due to compilation of the xtask itself
  - Enables Bevy contributors on any platform to run `cargo ci` to run linting -- if the default available Rust is the same version as on CI, then the command should give an identical result.
- [x] Use the xtask from official CI so there's only one place to update.
- [x] Bonus: Run clippy on the _entire_ workspace (existing CI setup was missing the `--workspace` flag
  - [x] Clean up newly-exposed clippy errors 

~#1388 builds on this to clean up newly discovered clippy errors -- I thought it might be nicer as a separate PR.~  Nope, merged it into this one so CI would pass.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
Nathan Stocks 2021-02-22 08:42:19 +00:00
parent c9f19d8663
commit 13b602ee3f
18 changed files with 63 additions and 49 deletions

View File

@ -1,4 +1,4 @@
# Rename this file to `config.toml` to enable "fast build" configuration. Please read the notes below. # Add the contents of this file to `config.toml` to enable "fast build" configuration. Please read the notes below.
# NOTE: For maximum performance, build using a nightly compiler # NOTE: For maximum performance, build using a nightly compiler
# If you are using rust stable, remove the "-Zshare-generics=y" below (as well as "-Csplit-debuginfo=unpacked" when building on macOS). # If you are using rust stable, remove the "-Zshare-generics=y" below (as well as "-Csplit-debuginfo=unpacked" when building on macOS).

View File

@ -34,13 +34,8 @@ jobs:
if: runner.os == 'linux' if: runner.os == 'linux'
- name: Check the format - name: Check the format
run: cargo fmt --all -- --check # See tools/ci/src/main.rs for the commands this runs
if: runner.os == 'linux' && matrix.toolchain == 'stable' run: cargo run --package ci
# -A clippy::type_complexity: type complexity must be ignored because we use huge templates for queries.
# -A clippy::manual-strip: strip_prefix support was added in 1.45. We want to support earlier rust versions.
- name: Clippy
run: cargo clippy --all-targets --all-features -- -D warnings -A clippy::type_complexity -A clippy::manual-strip
if: runner.os == 'linux' && matrix.toolchain == 'stable' if: runner.os == 'linux' && matrix.toolchain == 'stable'
- name: Build & run tests - name: Build & run tests

View File

@ -17,7 +17,7 @@ repository = "https://github.com/bevyengine/bevy"
[workspace] [workspace]
exclude = ["benches"] exclude = ["benches"]
members = ["crates/*", "examples/ios"] members = ["crates/*", "examples/ios", "tools/ci"]
[features] [features]
default = [ default = [

View File

@ -32,7 +32,7 @@ fn spawn_static(b: &mut Bencher) {
struct Bundle { struct Bundle {
pos: Position, pos: Position,
vel: Velocity, vel: Velocity,
}; }
let mut world = World::new(); let mut world = World::new();
b.iter(|| { b.iter(|| {
@ -48,7 +48,7 @@ fn spawn_batch(b: &mut Bencher) {
struct Bundle { struct Bundle {
pos: Position, pos: Position,
vel: Velocity, vel: Velocity,
}; }
let mut world = World::new(); let mut world = World::new();
b.iter(|| { b.iter(|| {

View File

@ -89,6 +89,7 @@ pub(crate) fn time_system(mut time: ResMut<Time>) {
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::float_cmp)]
mod tests { mod tests {
use super::Time; use super::Time;
use bevy_utils::{Duration, Instant}; use bevy_utils::{Duration, Instant};

View File

@ -157,6 +157,7 @@ impl Timer {
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::float_cmp)]
mod tests { mod tests {
use super::Timer; use super::Timer;

View File

@ -17,7 +17,7 @@ impl<'de> Deserialize<'de> for Entity {
where where
D: serde::Deserializer<'de>, D: serde::Deserializer<'de>,
{ {
Ok(deserializer.deserialize_u32(EntityVisitor)?) deserializer.deserialize_u32(EntityVisitor)
} }
} }

View File

@ -45,8 +45,7 @@ impl World {
/// Create an empty world /// Create an empty world
pub fn new() -> Self { pub fn new() -> Self {
// `flush` assumes archetype 0 always exists, representing entities with no components. // `flush` assumes archetype 0 always exists, representing entities with no components.
let mut archetypes = Vec::new(); let archetypes = vec![Archetype::new(Vec::new())];
archetypes.push(Archetype::new(Vec::new()));
let mut index = HashMap::default(); let mut index = HashMap::default();
index.insert(Vec::new(), 0); index.insert(Vec::new(), 0);
Self { Self {

View File

@ -1,4 +1,4 @@
use crate::{system::SystemId, AtomicBorrow, TypeInfo}; use crate::{system::SystemId, AtomicBorrow};
use bevy_utils::HashMap; use bevy_utils::HashMap;
use core::any::TypeId; use core::any::TypeId;
use downcast_rs::{impl_downcast, Downcast}; use downcast_rs::{impl_downcast, Downcast};
@ -204,15 +204,14 @@ impl Resources {
fn insert_resource<T: Resource>(&mut self, resource: T, resource_index: ResourceIndex) { fn insert_resource<T: Resource>(&mut self, resource: T, resource_index: ResourceIndex) {
let type_id = TypeId::of::<T>(); let type_id = TypeId::of::<T>();
let data = self.resource_data.entry(type_id).or_insert_with(|| { let data = self
let mut types = Vec::new(); .resource_data
types.push(TypeInfo::of::<T>()); .entry(type_id)
ResourceData { .or_insert_with(|| ResourceData {
storage: Box::new(VecResourceStorage::<T>::default()), storage: Box::new(VecResourceStorage::<T>::default()),
default_index: None, default_index: None,
system_id_to_archetype_index: HashMap::default(), system_id_to_archetype_index: HashMap::default(),
} });
});
let storage = data let storage = data
.storage .storage
@ -500,6 +499,7 @@ mod tests {
use crate::system::SystemId; use crate::system::SystemId;
#[test] #[test]
#[allow(clippy::float_cmp)]
fn resource() { fn resource() {
let mut resources = Resources::default(); let mut resources = Resources::default();
assert!(resources.get::<i32>().is_none()); assert!(resources.get::<i32>().is_none());

View File

@ -425,6 +425,7 @@ impl Commands {
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::float_cmp, clippy::approx_constant)]
mod tests { mod tests {
use crate::{resource::Resources, Commands, World}; use crate::{resource::Resources, Commands, World};
use core::any::TypeId; use core::any::TypeId;
@ -480,7 +481,7 @@ mod tests {
.map(|(a, b)| (*a, *b)) .map(|(a, b)| (*a, *b))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert_eq!(results_after, vec![]); assert_eq!(results_after, vec![]);
let results_after_u64 = world.query::<&u64>().map(|a| *a).collect::<Vec<_>>(); let results_after_u64 = world.query::<&u64>().copied().collect::<Vec<_>>();
assert_eq!(results_after_u64, vec![]); assert_eq!(results_after_u64, vec![]);
} }

View File

@ -56,6 +56,7 @@ pub use bevy_reflect_derive::*;
pub use erased_serde; pub use erased_serde;
#[cfg(test)] #[cfg(test)]
#[allow(clippy::blacklisted_name, clippy::approx_constant)]
mod tests { mod tests {
use ::serde::de::DeserializeSeed; use ::serde::de::DeserializeSeed;
use bevy_utils::HashMap; use bevy_utils::HashMap;
@ -67,6 +68,7 @@ mod tests {
use crate::serde::{ReflectDeserializer, ReflectSerializer}; use crate::serde::{ReflectDeserializer, ReflectSerializer};
use super::*; use super::*;
#[test] #[test]
fn reflect_struct() { fn reflect_struct() {
#[derive(Reflect)] #[derive(Reflect)]
@ -145,6 +147,7 @@ mod tests {
} }
#[test] #[test]
#[allow(clippy::blacklisted_name)]
fn reflect_unit_struct() { fn reflect_unit_struct() {
#[derive(Reflect)] #[derive(Reflect)]
struct Foo(u32, u64); struct Foo(u32, u64);

View File

@ -305,6 +305,7 @@ fn next_token<'a>(path: &'a str, index: &mut usize) -> Option<Token<'a>> {
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::float_cmp, clippy::approx_constant)]
mod tests { mod tests {
use super::GetPath; use super::GetPath;
use crate::*; use crate::*;

View File

@ -330,12 +330,12 @@ mod tests {
bindings.set("b", resource2.clone()); bindings.set("b", resource2.clone());
let mut different_bindings = RenderResourceBindings::default(); let mut different_bindings = RenderResourceBindings::default();
different_bindings.set("a", resource3.clone()); different_bindings.set("a", resource3);
different_bindings.set("b", resource4.clone()); different_bindings.set("b", resource4);
let mut equal_bindings = RenderResourceBindings::default(); let mut equal_bindings = RenderResourceBindings::default();
equal_bindings.set("a", resource1.clone()); equal_bindings.set("a", resource1.clone());
equal_bindings.set("b", resource2.clone()); equal_bindings.set("b", resource2);
let status = bindings.update_bind_group_status(&bind_group_descriptor); let status = bindings.update_bind_group_status(&bind_group_descriptor);
let id = if let BindGroupStatus::Changed(id) = status { let id = if let BindGroupStatus::Changed(id) = status {
@ -368,7 +368,7 @@ mod tests {
}; };
let mut unmatched_bindings = RenderResourceBindings::default(); let mut unmatched_bindings = RenderResourceBindings::default();
unmatched_bindings.set("a", resource1.clone()); unmatched_bindings.set("a", resource1);
let unmatched_bind_group_status = let unmatched_bind_group_status =
unmatched_bindings.update_bind_group_status(&bind_group_descriptor); unmatched_bindings.update_bind_group_status(&bind_group_descriptor);
assert_eq!(unmatched_bind_group_status, BindGroupStatus::NoMatch); assert_eq!(unmatched_bind_group_status, BindGroupStatus::NoMatch);

View File

@ -46,9 +46,9 @@ pub enum ShaderError {
not(target_arch = "wasm32"), not(target_arch = "wasm32"),
not(all(target_arch = "aarch64", target_os = "macos")) not(all(target_arch = "aarch64", target_os = "macos"))
))] ))]
impl Into<bevy_glsl_to_spirv::ShaderType> for ShaderStage { impl From<ShaderStage> for bevy_glsl_to_spirv::ShaderType {
fn into(self) -> bevy_glsl_to_spirv::ShaderType { fn from(s: ShaderStage) -> bevy_glsl_to_spirv::ShaderType {
match self { match s {
ShaderStage::Vertex => bevy_glsl_to_spirv::ShaderType::Vertex, ShaderStage::Vertex => bevy_glsl_to_spirv::ShaderType::Vertex,
ShaderStage::Fragment => bevy_glsl_to_spirv::ShaderType::Fragment, ShaderStage::Fragment => bevy_glsl_to_spirv::ShaderType::Fragment,
ShaderStage::Compute => bevy_glsl_to_spirv::ShaderType::Compute, ShaderStage::Compute => bevy_glsl_to_spirv::ShaderType::Compute,

View File

@ -269,6 +269,7 @@ impl<'scope, T: Send + 'scope> Scope<'scope, T> {
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::blacklisted_name)]
mod tests { mod tests {
use super::*; use super::*;
use std::sync::{ use std::sync::{

View File

@ -1,20 +0,0 @@
#!/usr/bin/env bash
# This script is intended to mimic some CI behavior that we encourage contributors to run locally.
# For the actual CI run on GitHub, see the files in .github/workflows/
# Exit when any command fails
set -e
# Keep track of the last executed command
trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
# Echo an error message before exiting, so you can see exactly what command and what error code
trap 'echo "\"${last_command}\" command filed with exit code $?."' EXIT
## ACTUAL COMMANDS
# Auto-format Rust files
cargo +nightly fmt --all
# Run a more intensive linter
cargo clippy --all-targets --all-features -- -D warnings -A clippy::type_complexity -A clippy::manual-strip

13
tools/ci/Cargo.toml Normal file
View File

@ -0,0 +1,13 @@
[package]
name = "ci"
version = "0.1.0"
authors = [
"Bevy Contributors <bevyengine@gmail.com>",
"Nathan Stocks <nathan@agileperception.com>"
]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
xshell = "0.1"

19
tools/ci/src/main.rs Normal file
View File

@ -0,0 +1,19 @@
use xshell::cmd;
fn main() {
// When run locally, results may from actual CI runs triggered by .github/workflows/ci.yml
// - Official CI runs latest stable
// - Local runs use whatever the default Rust is locally
// See if any code needs to be formatted
cmd!("cargo fmt --all -- --check")
.run()
.expect("Please run 'cargo fmt --all' to format your code.");
// See if clippy has any complaints.
// - Type complexity must be ignored because we use huge templates for queries
// - `-A clippy::manual-strip` strip_prefix support was added in 1.45
cmd!("cargo clippy --workspace --all-targets --all-features -- -D warnings -A clippy::type_complexity -A clippy::manual-strip")
.run()
.expect("Please fix clippy errors in output above.");
}