#
# Author: Hari Sekhon
# Date: 2013-02-03 10:25:36 +0000 (Sun, 03 Feb 2013)
#
# https://github.com/harisekhon/bash-tools
#
# License: see accompanying Hari Sekhon LICENSE file
#
# If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback
# to help improve or steer this or other code I publish
#
# https://www.linkedin.com/in/harisekhon
#
i f n e q ( "$(wildcard bash-tools)" , "" )
BASH_TOOLS := bash-tools
e l s e
BASH_TOOLS := .
e n d i f
export PATH := $( PATH) :/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin
DOCKER_IMAGE := harisekhon/centos-github
CODE_FILES := $( shell git ls-files | while read line; do test -f " $$ line " || continue ; echo " $$ line " ; done )
CPANM = cpanm
SUDO := sudo
SUDO_PIP := sudo -H
SUDO_PERL := sudo
PYTHON_VIRTUALENV :=
i f d e f P E R L B R E W _ P E R L
# can't put this here otherwise gets error - "commands commence before first target. Stop."
#@echo "Perlbrew environment detected, not calling sudo"
SUDO_PERL =
e n d i f
# Travis has custom python install earlier in $PATH even in Perl builds so need to install PyPI modules locally to non-system python otherwise they're not found by programs.
# Perms not set correctly on custom python install in Travis perl build so workaround is done to chown to travis user in .travis.yml
# Better than modifying $PATH to put /usr/bin first which is likely to affect many other things including potentially not finding the perlbrew installation first
# Looks like Perl travis builds are now using system Python - do not use TRAVIS env
i f d e f V I R T U A L _ E N V
#@echo "Virtual Env / Conda detected, not calling sudo"
SUDO_PIP :=
PYTHON_VIRTUALENV := 1
e n d i f
i f d e f C O N D A _ D E F A U L T _ E N V
SUDO_PIP :=
PYTHON_VIRTUALENV := 1
e n d i f
# must come after to reset SUDO_PERL/SUDO_PIP to blank if root
# EUID / UID not exported in Make
# USER not populated in Docker
i f e q '$(shell id -u)' '0'
#@echo "root UID detected, not calling sudo"
SUDO :=
SUDO_PERL :=
SUDO_PIP :=
e n d i f
.PHONY : default
default : build
@:
.PHONY : quick
quick :
QUICK = 1 $( MAKE) build
.PHONY : submodules
submodules :
git submodule update --init --recursive
.PHONY : git -clean
git-clean :
@git clean -n -d
@printf "\n\n%s" "If you're happy with this list, run:"
@printf "\n\n%s\n\n" "git clean -f -d"
.PHONY : gitignore
gitignore :
$( BASH_TOOLS) /update_gitignore.io.sh
.PHONY : btest
btest : bash -test
@:
.PHONY : bash -test
bash-test :
$( BASH_TOOLS) /all.sh
.PHONY : push
push :
git push
.PHONY : system -packages
system-packages : submodules
if [ -x /sbin/apk ] ; then $( MAKE) apk-packages; fi
if [ -x /usr/bin/apt-get ] ; then $( MAKE) apt-packages; fi
if [ -x /usr/bin/yum ] ; then $( MAKE) yum-packages; fi
if [ -x /usr/local/bin/brew -a ` uname` = Darwin ] ; then $( MAKE) homebrew-packages; fi
.PHONY : system -packages -perl
system-packages-perl : system -packages
if [ -x /sbin/apk ] ; then $( MAKE) apk-packages-perl; fi
if [ -x /usr/bin/apt-get ] ; then $( MAKE) apt-packages-perl; fi
if [ -x /usr/bin/yum ] ; then $( MAKE) yum-packages-perl; fi
.PHONY : system -packages -python
system-packages-python : system -packages
if [ -x /sbin/apk ] ; then $( MAKE) apk-packages-python; fi
if [ -x /usr/bin/apt-get ] ; then $( MAKE) apt-packages-python; fi
if [ -x /usr/bin/yum ] ; then $( MAKE) yum-packages-python; fi
.PHONY : apk -packages
apk-packages :
# not portable in Alpine sh
#for x in apk-packages{,-perl,-python}{,-dev}.txt; do \
for x in apk-packages.txt apk-packages-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /apk-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
#for x in apk-packages-{optional,cpan,pip}.txt; do \
for x in apk-packages-optional.txt; do \
if [ -f " setup/ $$ x " ] ; then \
NO_FAIL = 1 NO_UPDATE = 1 $( BASH_TOOLS) /apk-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : apk -packages -perl
apk-packages-perl :
for x in apk-packages-perl.txt apk-packages-perl-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /apk-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
#for x in apk-packages-{optional,cpan,pip}.txt; do \
for x in apk-packages-cpan.txt; do \
if [ -f " setup/ $$ x " ] && [ -n " $( PERLBREW_PERL) " ] ; then \
NO_FAIL = 1 NO_UPDATE = 1 $( BASH_TOOLS) /apk-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : apk -packages -python
apk-packages-python :
for x in apk-packages-python.txt apk-packages-python-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /apk-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
for x in apk-packages-pip.txt; do \
if [ -f " setup/ $$ x " ] && [ -n " $( PYTHON_VIRTUALENV) " ] ; then \
NO_FAIL = 1 NO_UPDATE = 1 $( BASH_TOOLS) /apk-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : apt -packages
apt-packages :
#for x in deb-packages{,-perl,-python}{,-dev}.txt; do \
for x in deb-packages.txt deb-packages-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /apt-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
#for x in deb-packages-{optional,cpan,pip}.txt; do \
for x in deb-packages-optional.txt; do \
if [ -f " setup/ $$ x " ] ; then \
NO_FAIL = 1 NO_UPDATE = 1 $( BASH_TOOLS) /apt-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : apt -packages -perl
apt-packages-perl :
for x in deb-packages-perl.txt deb-packages-perl-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /apt-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
for x in deb-packages-cpan.txt; do \
if [ -f " setup/ $$ x " ] && [ -n " $( PERLBREW_PERL) " ] ; then \
NO_FAIL = 1 NO_UPDATE = 1 $( BASH_TOOLS) /apt-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : apt -packages -python
apt-packages-python :
for x in deb-packages-python.txt deb-packages-python-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /apt-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
for x in deb-packages-pip.txt; do \
if [ -f " setup/ $$ x " ] && [ -n " $( PYTHON_VIRTUALENV) " ] ; then \
NO_FAIL = 1 NO_UPDATE = 1 $( BASH_TOOLS) /apt-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : yum -packages
yum-packages :
$( BASH_TOOLS) /setup/install_epel_repo.sh
# installing packages individually to catch package install failure, otherwise yum succeeds even if it misses a package
for x in rpm-packages.txt rpm-packages-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /yum-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
for x in rpm-packages-optional.txt; do \
if [ -f " setup/ $$ x " ] ; then \
NO_FAIL = 1 $( BASH_TOOLS) /yum-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : yum -packages -perl
yum-packages-perl :
# installing packages individually to catch package install failure, otherwise yum succeeds even if it misses a package
for x in rpm-packages-perl.txt rpm-packages-perl-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /yum-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
for x in rpm-packages-cpan.txt; do \
if [ -f " setup/ $$ x " ] && [ -n " $( PERLBREW_PERL) " ] ; then \
NO_FAIL = 1 $( BASH_TOOLS) /yum-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : yum -packages -python
yum-packages-python :
# installing packages individually to catch package install failure, otherwise yum succeeds even if it misses a package
for x in rpm-packages-python.txt rpm-packages-python-dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
$( BASH_TOOLS) /yum-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
for x in rpm-packages-pip.txt; do \
if [ -f " setup/ $$ x " ] && [ -n " $( PYTHON_VIRTUALENV) " ] ; then \
NO_FAIL = 1 $( BASH_TOOLS) /yum-install-packages.sh " setup/ $$ x " ; \
fi ; \
done
.PHONY : homebrew -packages
homebrew-packages :
# Fails if any of the packages are already installed, ignore and continue - if it's a problem the latest build steps will fail with missing headers
if test -f setup/brew-packages.txt; then NO_FAIL = 1 $( BASH_TOOLS) /brew-install-packages.sh setup/brew-packages.txt; fi
.PHONY : system -packages -remove
system-packages-remove :
if [ -x /sbin/apk ] ; then $( MAKE) apk-packages-remove; fi
if [ -x /usr/bin/apt-get ] ; then $( MAKE) apt-packages-remove; fi
if [ -x /usr/bin/yum ] ; then $( MAKE) yum-packages-remove; fi
.PHONY : apk -packages -remove
apk-packages-remove :
for x in lib pylib lib-java; do test -f " $$ x " && pushd " $$ X " && $( MAKE) apk-packages-remove; popd; done ; :
for x in apk-packages-{ ,perl-,python-} dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
NO_FAIL = 1 $( BASH_TOOLS) /apk-remove-packages.sh " setup/ $xx " ; \
fi ; \
done
$( SUDO) rm -fr /var/cache/apk/*
.PHONY : apt -packages -remove
apt-packages-remove :
for x in lib pylib lib-java; do test -f " $$ x " && pushd " $$ X " && $( MAKE) apt-packages-remove; popd; done ; :
for x in deb-packages-{ ,perl-,python-} dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
NO_FAIL = 1 $( BASH_TOOLS) /apt-remove-packages.sh " setup/ $xx " ; \
fi ; \
done
.PHONY : yum -packages -remove
yum-packages-remove :
for x in lib pylib lib-java; do test -f " $$ x " && pushd " $$ X " && $( MAKE) yum-packages-remove; popd; done ; :
for x in rpm-packages-{ ,perl-,python-} dev.txt; do \
if [ -f " setup/ $$ x " ] ; then \
NO_FAIL = 1 $( BASH_TOOLS) /yum-remove-packages.sh " setup/ $xx " ; \
fi ; \
done
.PHONY : cpan
cpan :
find . -name 'cpan-requirements*.txt' | xargs $( BASH_TOOLS) /perl_cpanm_install_if_absent.sh
.PHONY : pip
pip :
find . -name 'requirements.txt' | xargs $( BASH_TOOLS) /python_pip_install_if_absent.sh
.PHONY : fatpacks
fatpacks :
$( BASH_TOOLS) /perl_generate_fatpacks.sh *.pl
.PHONY : fatpack
fatpack : fatpacks
@:
.PHONY : sonar
sonar :
sonar-scanner
.PHONY : update
update : update 2 build
@:
.PHONY : update 2
update2 : update -no -recompile
@:
.PHONY : update -no -recompile
update-no-recompile :
git pull
$( MAKE) submodules
.PHONY : update -submodules
update-submodules :
git submodule update --init --remote
.PHONY : updatem
updatem : update -submodules
@:
.PHONY : docker -run
docker-run :
docker run -ti --rm ${ DOCKER_IMAGE } ${ ARGS }
.PHONY : run
run : docker -run
@:
.PHONY : docker -mount
docker-mount :
# --privileged=true is needed to be able to:
# mount -t tmpfs -o size=1m tmpfs /mnt/ramdisk
docker run -ti --rm --privileged= true -v $$ PWD:/code ${ DOCKER_IMAGE } bash -c "cd /code; exec bash"
.PHONY : docker -mount -alpine
docker-mount-alpine :
# --privileged=true is needed to be able to:
# mount -t tmpfs -o size=1m tmpfs /mnt/ramdisk
docker run -ti --rm --privileged= true -v $$ PWD:/code ${ DOCKER_IMAGE } :alpine bash -c "cd /code; exec bash"
.PHONY : docker -mount -debian
docker-mount-debian :
# --privileged=true is needed to be able to:
# mount -t tmpfs -o size=1m tmpfs /mnt/ramdisk
docker run -ti --rm --privileged= true -v $$ PWD:/code ${ DOCKER_IMAGE } :debian bash -c "cd /code; exec bash"
.PHONY : docker -mount -centos
docker-mount-centos :
# --privileged=true is needed to be able to:
# mount -t tmpfs -o size=1m tmpfs /mnt/ramdisk
docker run -ti --rm --privileged= true -v $$ PWD:/code ${ DOCKER_IMAGE } :centos bash -c "cd /code; exec bash"
.PHONY : docker -mount -ubuntu
docker-mount-ubuntu :
# --privileged=true is needed to be able to:
# mount -t tmpfs -o size=1m tmpfs /mnt/ramdisk
docker run -ti --rm --privileged= true -v $$ PWD:/code ${ DOCKER_IMAGE } :ubuntu bash -c "cd /code; exec bash"
.PHONY : mount
mount : docker -mount
@:
.PHONY : mount -alpine
mount-alpine : docker -mount -alpine
@:
.PHONY : mount -debian
mount-debian : docker -mount -debian
@:
.PHONY : mount -centos
mount-centos : docker -mount -centos
@:
.PHONY : mount -ubuntu
mount-ubuntu : docker -mount -ubuntu
@:
# For quick testing only - for actual Dockerfile builds see https://hub.docker.com/u/harisekhon and Dockerfiles source repo https://github.com/harisekhon/Dockerfiles
.PHONY : docker -alpine
docker-alpine :
$( BASH_TOOLS) /docker_mount_build_exec.sh alpine
.PHONY : docker -debian
docker-debian :
$( BASH_TOOLS) /docker_mount_build_exec.sh debian
.PHONY : docker -centos
docker-centos :
$( BASH_TOOLS) /docker_mount_build_exec.sh centos
.PHONY : docker -ubuntu
docker-ubuntu :
$( BASH_TOOLS) /docker_mount_build_exec.sh ubuntu
.PHONY : travis
travis :
@source $( BASH_TOOLS) /.bash.d/network.sh; browser " https://travis-ci.org/ $( REPO) "
.PHONY : travis -log
travis-log :
travis_last_log.py --failed $( REPO)
.PHONY : travis -debug
travis-debug :
travis_debug_session.py $( REPO)
.PHONY : browse
browse :
@source $( BASH_TOOLS) /.bash.d/network.sh; browser " https://github.com/ $( REPO) "
.PHONY : readme
readme :
@source $( BASH_TOOLS) /.bash.d/network.sh; browser " https://github.com/ $( REPO) /blob/master/README.md "
.PHONY : startrack
startrack :
@echo "Don't run this too much, you will hit an API limit against your IP"
@source $( BASH_TOOLS) /.bash.d/network.sh; \
browser " https://seladb.github.io/StarTrack-js/?\
u = $$ ( sed 's/\/.*//' <<< " $( REPO) " ) \
& r = $$ ( sed 's/.*\///' <<< " $( REPO) " ) "
.PHONY : star
star : startrack
@:
.PHONY : allstars
allstars :
@echo "Takes a while, don't run this all the time or you will an API limit against your IP"
@REPOS= "Nagios-Plugins Dockerfiles DevOps-Python-tools DevOps-Perl-tools DevOps-Bash-Tools Nagios-Plugin-Kafka HAProxy-configs" ; \
source $( BASH_TOOLS) /.bash.d/network.sh; \
browser " https://seladb.github.io/StarTrack-js/?\
$$ ( \
for repo in $$ REPOS; do \
printf "%s" " &u=HariSekhon&r= $$ repo " ; \
done | \
sed 's/\&//' \
) "
.PHONY : ls -files
ls-files :
@echo $( CODE_FILES) | tr ' ' '\n' | sort
.PHONY : files
files : ls -files
@:
.PHONY : ls -code
ls-code :
@# TODO: port out my code and non-code lists and make this more generic
@$( MAKE) ls-files | grep -v -e '^\./\.' -e LICENSE -e '.*\.md' -e '.*\.txt' ` for x in $( CONF_FILES) $( shell git submodule | awk '{print $$2}' ) ; do echo " -e $$ x " ; done `
@$( MAKE) ls-files | grep '\.bash' || :
.PHONY : lscode
lscode : ls -code
@:
.PHONY : wc
wc :
@# CODE_FILES := definitions in Makefiles must not be quoted or will get wc error 'open: File name too long'
@wc -l $( CODE_FILES)
@printf "Total Files: "
@tr ' ' '\n' <<< " $( CODE_FILES) " | wc -l
.PHONY : wc 2
wc2 :
@printf "Total Files: "
@tr ' ' '\n' <<< " $( CODE_FILES) " | wc -l
@printf "Total line count without # comments:"
@sed 's/#.*//;/^[[:space:]]*$$/d' $( CODE_FILES) | wc -l
.PHONY : wc -code
wc-code :
@$( MAKE) ls-code | xargs wc -l
@printf "Total code files: "
@$( MAKE) ls-code | wc -l
.PHONY : wccode
wccode : wc -code
@:
.PHONY : wc -code 2
wc-code2 :
@printf "Total code files: "
@$( MAKE) ls-code | wc -l
@printf "Total line count without # comments: "
@$( MAKE) ls-code | xargs sed 's/#.*//;/^[[:space:]]*$$/d' | wc -l
.PHONY : wccode
wccode2 : wc -code 2
@:
# finds .swp, would need to port out code lists
#.PHONY: wcall
#wcall:
# find . -type f --not -path '*.git*' -exec cat {} \; | wc -l
#
#.PHONY: wcall
#wcall:
# find . -type f -not -path '*.git*' -exec sed 's/#.*//;/^[[:space:]]*$$/d' {} \; | wc -l