yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
eda080bbf
master
1#!/usr/bin/env bash 2 3set -e 4 5# Check Bash version 6if [" ${ BASH_VERSINFO [0]} " -lt 4 ];then 7echo "Error: Bash 4 or newer is required. Current version: $ BASH_VERSION " >&2 8if [[" $( uname ) " =="Darwin" ]];then 9echo "Please install a newer version of Bash using Homebrew:" >&2 10echo " brew install bash" >&2 11fi 12exit 1 13fi 14 15script_dir =" $( cd " $( dirname " ${ BASH_SOURCE [0]} " ) " > /dev/null 2 >&1 && pwd ) " 16source_dir =" $( dirname " $ script_dir " ) " 17since_rev ="" 18 19# Detect macOS and set appropriate binary names 20if [[" $( uname ) " =="Darwin" ]];then 21# On macOS, check for GNU versions 22# grep and xargs use g-prefix, diff is installed as /opt/homebrew/bin/diff 23missing_tools =() 24 25if !command -v ggrep &>/dev/null;then 26missing_tools +=("grep" ) 27fi 28 29if !command -v gxargs &>/dev/null;then 30missing_tools +=("findutils" ) 31fi 32 33if !command -v /opt/homebrew/bin/diff &>/dev/null;then 34missing_tools +=("diffutils" ) 35fi 36 37if [${# missing_tools [@]} -gt 0 ];then 38echo "Error: GNU versions of grep, xargs, and diff are required on macOS." >&2 39echo "Please install them using Homebrew:" >&2 40echo " brew install ${ missing_tools [*]} " >&2 41exit 1 42fi 43 44GREP_BIN ="ggrep" 45XARGS_BIN ="gxargs" 46DIFF_BIN ="/opt/homebrew/bin/diff" 47else 48# On other systems, use standard binaries 49GREP_BIN ="grep" 50XARGS_BIN ="xargs" 51DIFF_BIN ="diff" 52fi 53 54check_only =0 55no_version_check =0 56modified_files =0 57run_cpp =0 58run_yaml =0 59run_markdown =0 60run_sh =0 61run_cmake =0 62run_all =1 63 64show_help () { 65me =$( basename " $ 0" ) 66cat <<EOF 67$ me : Format or check formatting of files in this repo 68 69Usage: $ me [--check-only] [--no-version-check] [--source <path>] [--cpp] [--yaml] [--md] [--sh] [--cmake] 70 71Options: 72--check-only Check formatting without modifying files 73--no-version-check Skip version compatibility checks 74--source Path to source directory to format (defaults to parent of script directory) 75--cpp Format only C++ files 76--yaml Format only YAML/JSON files 77--md Format only markdown files 78--sh Format only shell script files 79--cmake Format only CMake files 80--since <rev> Only format files since Git revision <rev> 81EOF 82} 83 84while [[" $ #" -gt 0 ]];do 85case $ 1 in 86 -h| --help) 87show_help 88exit 0 89 ;; 90 --check-only)check_only =1 ;; 91 --no-version-check)no_version_check =1 ;; 92 --modified)modified_files =1 ;; 93 --cpp) 94run_cpp =1 95run_all =0 96 ;; 97 --yaml) 98run_yaml =1 99run_all =0 100 ;; 101 --md) 102run_markdown =1 103run_all =0 104 ;; 105 --sh) 106run_sh =1 107run_all =0 108 ;; 109 --cmake) 110run_cmake =1 111run_all =0 112 ;; 113 --source) 114source_dir =" $ 2 " 115shift 116 ;; 117 --since) 118since_rev =" $ 2 " 119shift 120 ;; 121 *) 122echo "unrecognized argument: $ 1 " 123show_help 124exit 1 125 ;; 126esac 127shift 128done 129 130cd " $ source_dir " ||exit 1 131 132require_bin () { 133 localname =" $ 1 " 134 localmin_version =" $ 2 " 135 localmax_version =" ${ 3 :-} " 136 localversion 137 138if !command -v " $ name " &>/dev/null;then 139echo "This script needs $ name , but it isn't in \$PATH" >&2 140missing_bin =1 141return 142fi 143 144if [" $ no_version_check " -eq 0 ];then 145version =$( " $ name " --version | $ GREP_BIN -oP "\d+\.\d+\.?\d*" | head -n1 ) 146 147# Debug output to stderr 148if [ -n" $ max_version " ];then 149echo "found $ name $ version , required [ $ min_version , $ max_version )" >&2 150else 151echo "found $ name $ version , required at least $ min_version " >&2 152fi 153 154if !printf '%s\n%s\n' " $ min_version " " $ version " | sort -V -C ;then 155echo " $ name version $ version is too old. Version $ min_version or newer is required." >&2 156missing_bin =1 157return 158fi 159 160if [ -n" $ max_version " ];then 161if !printf '%s\n%s\n' " $ version " " $ max_version " | sort -V -C ;then 162echo " $ name version $ version is too new. Version less than $ max_version is required." >&2 163missing_bin =1 164return 165fi 166fi 167fi 168} 169 170require_bin "git" "1.8" 171(( run_all || run_cmake )) && require_bin "gersemi" "0.21" "0.22" 172(( run_all || run_cpp )) && require_bin " $ XARGS_BIN " "3" 173require_bin " $ DIFF_BIN " "2" 174(( run_all || run_cpp )) && require_bin "clang-format" "17" "18" 175(( run_all || run_yaml || run_markdown )) && require_bin "prettier" "3" 176(( run_all || run_sh )) && require_bin "shfmt" "3" 177 178if [" $ missing_bin " ];then 179exit 1 180fi 181 182get_nproc () { 183 localnproc_count 184if command -v nproc &>/dev/null;then 185nproc_count =$( nproc ) 186elif [[" $( uname ) " =="Darwin" ]]&& command -v sysctl &>/dev/null;then 187nproc_count =$( sysctl -n hw.logicalcpu) 188elif command -v getconf &>/dev/null;then 189nproc_count =$( getconf _NPROCESSORS_ONLN 2 > /dev/null) 190fi 191echo " ${ nproc_count :-1} " 192} 193 194exit_code =0 195 196function list_files () { 197if [" $ since_rev " ] || [" $ modified_files " -eq 1 ];then 198command ="git diff --name-only" 199if [" $ since_rev " ];then 200command =" $ command $ since_rev " 201else 202command =" $ command HEAD" 203fi 204if [" $ modified_files " -eq 0 ];then 205command =" $ command HEAD" 206fi 207$ command " $ @" 208else 209git ls-files$ @ 210fi 211} 212 213cmake_formatting () { 214echo "Formatting CMake files..." >&2 215 216readarray -t files< <( list_files '*.cmake' 'CMakeLists.txt' '**/CMakeLists.txt' ) 217 218common_args =( 219# turn on warning when this is fixed https://github.com/BlankSpruce/gersemi/issues/39 220 --no-warn-about-unknown-commands 221 --definitions" ${ files [@]} " 222 ) 223 224if [" $ check_only " -eq 1 ];then 225gersemi " ${ common_args [@]} " --diff --color " ${ files [@]} " 226gersemi " ${ common_args [@]} " --check " ${ files [@]} " ||exit_code =1 227else 228gersemi " ${ common_args [@]} " --in-place " ${ files [@]} " 229fi 230} 231 232track_progress () { 233# Don't output the progress bar if stderr isn't a terminal, just eat all the input 234 [ -t 2 ] || { 235cat > /dev/null 236return 237 } 238 239 localtotal =$ 1 240 localcurrent =0 241 242(( total )) && while IFS =read -r _;do 243 ((current++)) ||: 244percent =$((current * 100 /total )) 245printf '\rProgress: [%-50s] %d%%' " $( printf '#%.0s' $( seq 1 $(( percent / 2)))) " " $ percent " >&2 246done 247echo >&2 248} 249 250cpp_formatting () { 251echo "Formatting cpp files..." >&2 252 253readarray -t files< <( list_files '*.cpp' '*.hpp' '*.c' '*.h' ':!external/**' ) 254 255# The progress reporting is a bit sneaky, we use `--verbose` with xargs which 256# prints a line to stderr for each command, and we simply count these... 257 258if [" $ check_only " -eq 1 ];then 259 localtmpdir 260tmpdir =$( mktemp -d ) 261trap 'rm -rf "$tmpdir"' EXIT 262 263printf '%s\n' " ${ files [@]} " | $ XARGS_BIN --verbose -P " $( get_nproc ) " -I{} bash-c " 264mkdir -p \"\$(dirname \" $ tmpdir /{}\")\" 265$ DIFF_BIN -u --color=always --label \"{}\" --label \"{}\" \"{}\" <(clang-format \"{}\") > \" $ tmpdir /{}\" 266: 267" |&track_progress ${# files [@]} 268 269for file in " ${ files [@]} " ;do 270# Fail if any of the diffs have contents 271if [ -s" $ tmpdir / $ file " ];then 272cat " $ tmpdir / $ file " 273exit_code =1 274fi 275done 276else 277printf '%s\n' " ${ files [@]} " | $ XARGS_BIN --verbose -n1 -P " $( get_nproc ) " clang-format-i |& 278track_progress ${# files [@]} 279fi 280} 281 282# Format the 'files' array using the prettier tool (abstracted here because 283# it's used by markdown and json 284prettier_formatting () { 285if [" $ check_only " -eq 1 ];then 286for file in " ${ files [@]} " ;do 287if !output =$( prettier " $ file " 2 > /dev/null) ;then 288continue 289fi 290if !$ DIFF_BIN -q " $ file " <( echo " $ output " ) > /dev/null2 >&1;then 291$ DIFF_BIN --color -u --label " $ file " --label " $ file " " $ file " <( echo " $ output " ) ||: 292exit_code =1 293fi 294done 295else 296prettier --write " ${ files [@]} " | $ GREP_BIN -v '(unchanged)' >&2 ||: 297fi 298} 299 300yaml_json_formatting () { 301echo "Formatting yaml and json files..." >&2 302 303readarray -t files< <( list_files "*.yaml" "*.yml" "*.json" ':!external/**' ) 304 305prettier_formatting 306} 307 308markdown_formatting () { 309echo "Formatting markdown files..." >&2 310 311readarray -t files< <( list_files "*.md" ':!external/**' ) 312 313prettier_formatting 314} 315 316sh_formatting () { 317echo "Formatting sh files..." >&2 318 319readarray -t files< <( list_files "*.sh" ) 320 321common_args =( 322# default 8 is way too wide 323 --indent 2 324 ) 325 326if [" $ check_only " -eq 1 ];then 327shfmt " ${ common_args [@]} " --diff " ${ files [@]} " ||exit_code =1 328else 329shfmt " ${ common_args [@]} " --write " ${ files [@]} " 330fi 331} 332 333(( run_all || run_sh )) && sh_formatting 334(( run_all || run_cmake )) && cmake_formatting 335(( run_all || run_yaml )) && yaml_json_formatting 336(( run_markdown )) && markdown_formatting 337(( run_all || run_cpp )) && cpp_formatting 338 339exit $ exit_code