We have many scripts that are defined as ERB templates.
We often make simple errors when editing them, as there's no tooling for dealing with such a format -- and in fact it's quite hard to write tooling for such, given the format of Puppet catalogs (which elides which template file produced a given generated file).
Instead, let's forbid scripts being generated from templates. (And also set up shellcheck for .sh files.)
Audit
The following one liner helps auditing said candidates: for file in $(find . -not -path "./.bundle/*" -name "*.erb"); do if head -1 "$file" | grep -q '^#!\/'; then wc -l "$file"; fi; done | sort -n
So for example in puppet as of 2f2ae5d303df2 we have:
3 ./modules/community_civicrm/templates/civicrm/community_civicrm_path.sh.erb 3 ./modules/dumps/templates/rsync/run_rsync.erb 3 ./modules/mariadb/templates/mysql-section.sh.erb 4 ./modules/openstack/templates/util/envscript.sh.erb 5 ./modules/gitlab/templates/gitlab-backup-config.sh.erb 7 ./modules/conftool/templates/conftool-merge.erb 7 ./modules/fastnetmon/templates/fastnetmon_notify.sh.erb 8 ./modules/conftool/templates/safe-depool.erb 8 ./modules/conftool/templates/safe-pool.erb 8 ./modules/profile/templates/ncredir/ncredirlog.sh.erb 8 ./modules/profile/templates/puppetserver/git/private/hooks/post-receive.erb 8 ./modules/profile/templates/quarry/trove/dbdump.sh.erb 8 ./modules/profile/templates/quarry/trove/dbdumpcleanup.sh.erb 8 ./modules/profile/templates/trafficserver/atslog.sh.erb 9 ./modules/profile/templates/prometheus/node-directory-size.erb 9 ./modules/service/templates/check-service.erb 9 ./modules/vagrant/templates/mwvagrant.erb 9 ./modules/vagrant/templates/start-mwvagrant.sh.erb 10 ./modules/role/templates/mariadb/backups/dumps-otrs.sh.erb 11 ./modules/base/templates/initramfs_sleep.erb 11 ./modules/package_builder/templates/D04php.erb 11 ./modules/snapshot/templates/set_dump_dirs.sh.erb 12 ./modules/docker/templates/images/build-base-images.erb 12 ./modules/phabricator/templates/vcs/phabricator-ssh-hook.sh.erb 12 ./modules/profile/templates/mediawiki/restart-php-fpm-all.sh.erb 12 ./modules/vagrant/templates/labs-vagrant.erb 13 ./modules/conftool/templates/safe-restart.erb 13 ./modules/elasticsearch/templates/set-cross-cluster-seeds.sh.erb 13 ./modules/monitoring/templates/check_dir-not-bad-owner.erb 13 ./modules/ncmonitor/templates/ncmonitor-update-psl.sh.erb 13 ./modules/profile/templates/presto/presto_client_ssl_kerberos.erb 13 ./modules/service/templates/node/tail-log.erb 13 ./modules/snapshot/templates/dumps/nfs_testing/test_outputdir_paths.sh.erb 14 ./modules/package_builder/templates/D02backports.erb 14 ./modules/package_builder/templates/D04component.erb 14 ./modules/package_builder/templates/D05localsources.erb 14 ./modules/profile/templates/analytics/refinery/job/refinery-drop-mediawiki-xmldumps-pages_meta_history.sh.erb 14 ./modules/profile/templates/kerberos/replicate_krb_database.erb 15 ./modules/service/templates/node/apply-config.sh.erb 16 ./modules/opensearch/templates/set-cross-cluster-seeds.sh.erb 16 ./modules/package_builder/templates/D01security.erb 16 ./modules/profile/templates/analytics/refinery/job/refinery-sqoop-whole-mediawiki.sh.erb 16 ./modules/profile/templates/kubernetes/kube-conf.sh.erb 17 ./modules/profile/templates/analytics/airflow/airflow.sh.erb 19 ./modules/conftool/templates/initialize.sh.erb 20 ./modules/profile/templates/analytics/airflow/airflow-clean-log-dirs.erb 20 ./modules/profile/templates/analytics/refinery/job/java_job.sh.erb 20 ./modules/profile/templates/analytics/refinery/job/refinery-import-mediawiki-dumps.sh.erb 20 ./modules/profile/templates/icinga/inactive.motd.erb 21 ./modules/profile/templates/analytics/refinery/job/refinery-sqoop-mediawiki-production-history.sh.erb 21 ./modules/profile/templates/analytics/refinery/job/refinery-sqoop-mediawiki-production-not-history.sh.erb 22 ./modules/package_builder/templates/D01apt.wikimedia.org.erb 22 ./modules/profile/templates/analytics/refinery/job/refinery-sqoop-mediawiki-not-history.sh.erb 22 ./modules/profile/templates/analytics/refinery/job/spark_job.sh.erb 23 ./modules/airflow/templates/airflow.sh.erb 23 ./modules/openstack/templates/initscripts/nova-fullstack.erb 23 ./modules/profile/templates/analytics/refinery/job/refinery-import-wikibase-dumps.sh.erb 23 ./modules/profile/templates/analytics/refinery/job/refinery-sqoop-mediawiki-history.sh.erb 23 ./modules/profile/templates/analytics/refinery/job/refinery-sqoop-mediawiki-private.sh.erb 23 ./modules/profile/templates/analytics/refinery/job/refinery-sqoop-mediawiki-production-daily.sh.erb 23 ./modules/profile/templates/debmonitor/server/run_django_command.sh.erb 23 ./modules/profile/templates/mediawiki/maintenance/inactive.motd.erb 23 ./modules/role/templates/deployment/inactive.motd.erb 24 ./modules/profile/templates/kerberos/kadminserver/inactive.motd.erb 24 ./modules/statistics/templates/published-sync.sh.erb 26 ./modules/profile/templates/analytics/refinery/job/refinery-sqoop-wikifunctions-production.sh.erb 26 ./modules/role/templates/releases/rsync_source_warning.motd.erb 28 ./modules/profile/templates/dns/auth/check_state.erb 28 ./modules/rsync/templates/quickdatacopy-ssl-wrapper.erb 32 ./modules/aptrepo/templates/ztp-juniper.sh.erb 32 ./modules/profile/templates/puppetserver/gitprivate/postcommit.erb 33 ./modules/monitoring/templates/check_git-needs-merge.erb 33 ./modules/profile/templates/hadoop/net-topology.py.erb 36 ./modules/puppetmaster/templates/git-master-postcommit.erb 39 ./modules/git/templates/replicated_local_postcommit.sh.erb 39 ./modules/profile/templates/dns/auth/check_authdns_update_run.erb 40 ./modules/profile/templates/analytics/refinery/job/refinery-salt-rotate.erb 41 ./modules/acme_chief/templates/create_acme_le_account.py.erb 42 ./modules/osm/templates/import_waterlines.erb 48 ./modules/openstack/templates/bootstrap/glance/glance_seed.sh.erb 49 ./modules/postgresql/templates/prometheus/postgresql_replication_lag.sh.erb 50 ./modules/phabricator/templates/phab_deploy_finalize.sh.erb 60 ./modules/httpbb/templates/deploy_apache_change.sh.erb 61 ./modules/backup/templates/mysql-predump.erb 65 ./modules/profile/templates/toolforge/harbor/prepare.erb 69 ./modules/bacula/templates/bpipe-mysql-db.erb 69 ./modules/haproxy/templates/check_haproxy.erb 73 ./modules/profile/templates/statistics/explorer/ml/model_upload.sh.erb 95 ./modules/spamassassin/templates/sa-update-cron.erb 110 ./modules/bigtop/templates/spark/spark-env.sh.erb 138 ./modules/labstore/templates/tc-setup.sh.erb 148 ./modules/beta/templates/wmf-beta-autoupdate.py.erb 157 ./modules/service/templates/deployment_script.sh.erb 179 ./modules/profile/templates/hadoop/spark3/spark3-env.sh.erb 224 ./modules/openstack/templates/bobcat/barbican/barbican-api.erb 224 ./modules/openstack/templates/caracal/barbican/barbican-api.erb 261 ./modules/openstack/templates/caracal/keystone/keystone-admin-service.erb 261 ./modules/openstack/templates/caracal/keystone/keystone-public-service.erb 262 ./modules/openstack/templates/bobcat/heat/heat-api-cfn.erb 262 ./modules/openstack/templates/bobcat/heat/heat-api.erb 262 ./modules/openstack/templates/caracal/heat/heat-api-cfn.erb 262 ./modules/openstack/templates/caracal/heat/heat-api.erb 265 ./modules/openstack/templates/bobcat/keystone/keystone-admin-service.erb 265 ./modules/openstack/templates/bobcat/keystone/keystone-public-service.erb 266 ./modules/openstack/templates/bobcat/magnum/magnum-api.erb 266 ./modules/openstack/templates/caracal/magnum/magnum-api.erb 270 ./modules/openstack/templates/bobcat/placement/placement-api.erb 270 ./modules/openstack/templates/caracal/placement/placement-api.erb