11#! /usr/bin/env bash
22set  -euo pipefail
3- PINNED=" ${PINNED:- 1.68.0} " 
3+ PINNED=" ${PINNED:- 1.71.1} " 
4+ #  MSRV floor for library checks (override with MSRV env)
5+ MSRV=" ${MSRV:- 1.71.1} " 
46
57for  cmd  in  cargo rustup rg;  do 
68  if  !  command  -v " $cmd " > /dev/null 2>&1 ;  then 
@@ -15,34 +17,76 @@ if [[ "${SKIP_HOOKS:-}" == 1 ]]; then
1517  exit  0
1618fi 
1719
18- echo  " [pre-push] fmt" 
19- cargo + " $PINNED "   fmt --all -- --check
20+ echo  " [pre-push] fmt (default toolchain) " 
21+ cargo fmt --all -- --check
2022
21- echo  " [pre-push] clippy (workspace)" 
22- cargo + " $PINNED "   clippy --all-targets -- -D warnings -D missing_docs
23+ echo  " [pre-push] clippy (workspace, default toolchain )" 
24+ cargo clippy --all-targets -- -D warnings -D missing_docs
2325
24- echo  " [pre-push] tests (workspace)" 
25- cargo + " $PINNED "   test  --workspace
26+ echo  " [pre-push] tests (workspace, default toolchain )" 
27+ cargo test  --workspace
2628
27- #  MSRV check for rmg-core
28- echo  " [pre-push] MSRV check (rmg-core @ $PINNED )" 
29- if  rustup run " $PINNED " > /dev/null 2>&1 ;  then 
30-   cargo +" $PINNED " 
29+ echo  " [pre-push] Testing against MSRV ${MSRV}  (core libraries)" 
30+ #  If any participating crate declares a rust-version greater than MSRV, skip MSRV checks entirely.
31+ CORE_RV=$( awk -F ' "' ' /^rust-version/ {print $2}' 2> /dev/null ||  echo  " " ) 
32+ GEOM_RV=$( awk -F ' "' ' /^rust-version/ {print $2}' 2> /dev/null ||  echo  " " ) 
33+ if  { [[ -n  " $CORE_RV " &&  printf  ' %s\n%s\n' " $MSRV " " $CORE_RV " |  sort -V |  tail -n1 |  grep -qx " $CORE_RV " &&  [[ " $CORE_RV " !=  " $MSRV " ;  } \
34+    ||  { [[ -n  " $GEOM_RV " &&  printf  ' %s\n%s\n' " $MSRV " " $GEOM_RV " |  sort -V |  tail -n1 |  grep -qx " $GEOM_RV " &&  [[ " $GEOM_RV " !=  " $MSRV " ;  };  then 
35+   echo  " [pre-push] Skipping MSRV block: one or more crates declare rust-version > ${MSRV}  (core=${CORE_RV:- unset} , geom=${GEOM_RV:- unset} )" 
3136else 
32-   echo  " [pre-push] MSRV toolchain $PINNED  not installed. Install via: rustup toolchain install $PINNED " >&2 
33-   exit  1
37+   if  !  rustup run " $MSRV " > /dev/null 2>&1 ;  then 
38+     echo  " [pre-push] MSRV toolchain ${MSRV}  not installed. Install via: rustup toolchain install ${MSRV} " >&2 
39+     exit  1
40+   fi 
41+   #  Only run MSRV tests for crates that declare rust-version <= MSRV; skip otherwise.
42+   msrv_ok () {
43+     local  crate=" $1 " 
44+     local  rv
45+     rv=$( awk -F ' "' ' /^rust-version/ {print $2}' " crates/${crate} /Cargo.toml" 2> /dev/null ||  echo  " " ) 
46+     if  [[ -z  " $rv " ;  then 
47+       return  0
48+     fi 
49+     #  If declared rust-version is greater than MSRV, skip.
50+     if  printf  ' %s\n%s\n' " $MSRV " " $rv " |  sort -V |  tail -n1 |  grep -qx " $rv " &&  [[ " $rv " !=  " $MSRV " ;  then 
51+       echo  " [pre-push] Skipping MSRV test for ${crate}  (rust-version ${rv}  > MSRV ${MSRV} )" 
52+       return  1
53+     fi 
54+     #  If crate depends on workspace rmg-core whose rust-version exceeds MSRV, skip as well
55+     if  grep -qE ' ^rmg-core\s*=\s*\{[^}]*path\s*=\s*"\.\./rmg-core"' " crates/${crate} /Cargo.toml" 2> /dev/null;  then 
56+       local  core_rv
57+       core_rv=$( awk -F ' "' ' /^rust-version/ {print $2}' " crates/rmg-core/Cargo.toml" 2> /dev/null ||  echo  " " ) 
58+       if  [[ -n  " $core_rv " &&  printf  ' %s\n%s\n' " $MSRV " " $core_rv " |  sort -V |  tail -n1 |  grep -qx " $core_rv " &&  [[ " $core_rv " !=  " $MSRV " ;  then 
59+         echo  " [pre-push] Skipping MSRV test for ${crate}  (depends on rmg-core ${core_rv}  > MSRV ${MSRV} )" 
60+         return  1
61+       fi 
62+     fi 
63+     return  0
64+   }
65+   if  msrv_ok rmg-core;  then  cargo +" $MSRV " test  -p rmg-core --all-targets;  fi 
66+   if  msrv_ok rmg-geom;  then  cargo +" $MSRV " test  -p rmg-geom --all-targets;  fi 
3467fi 
3568
36- #  Rustdoc warnings guard (core API )
37- echo  " [pre-push] rustdoc warnings gate (rmg-core)" 
69+ #  Rustdoc warnings guard (public crates )
70+ echo  " [pre-push] rustdoc warnings gate (rmg-core @  $PINNED )" 
3871RUSTDOCFLAGS=" -D warnings" " $PINNED " 
72+ echo  " [pre-push] rustdoc warnings gate (rmg-geom @ $PINNED )" 
73+ RUSTDOCFLAGS=" -D warnings" " $PINNED " 
3974
4075#  Banned patterns
4176echo  " [pre-push] scanning banned patterns" 
42- #  Match any crate-level allow(...) that includes missing_docs; exclude telemetry.rs explicitly
43- if  rg -n ' #!\[allow\([^]]*missing_docs[^]]*\)\]' ' !crates/rmg-core/src/telemetry.rs' > /dev/null;  then 
77+ #  Forbid crate-level allow(missing_docs) in library source files, but allow in tests and build scripts
78+ if  rg -n ' #!\[allow\([^]]*missing_docs[^]]*\)\]' 
79+   crates \
80+   --glob ' crates/**/src/**/*.rs' 
81+   --glob ' !**/telemetry.rs' 
82+   --glob ' !**/tests/**' 
83+   --glob ' !**/build.rs' > /dev/null;  then 
4484  echo  " pre-push: crate-level allow(missing_docs) is forbidden (except telemetry.rs)." >&2 
45-   rg -n ' #!\[allow\([^]]*missing_docs[^]]*\)\]' ' !crates/rmg-core/src/telemetry.rs' |  cat >&2  ||  true 
85+   rg -n ' #!\[allow\([^]]*missing_docs[^]]*\)\]' 
86+     --glob ' crates/**/src/**/*.rs' 
87+     --glob ' !**/telemetry.rs' 
88+     --glob ' !**/tests/**' 
89+     --glob ' !**/build.rs' |  cat >&2  ||  true 
4690  exit  1
4791fi 
4892if  rg -n " \#\[unsafe\(no_mangle\)\]" > /dev/null;  then 
0 commit comments