2025-07-10 08:13:49 +02:00
# Strict mode
SHELL := bash
.SHELLFLAGS := -eu -o pipefail -c
.ONESHELL :
.DELETE_ON_ERROR :
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
.PHONY : help dist -clean dist package build install test doc nsis
# Get a version string from git
2021-12-03 14:12:45 +01:00
CUR_SHA = $( shell git log -n1 --pretty= '%h' )
CUR_BRANCH = $( shell git branch --show-current)
2025-07-10 08:13:49 +02:00
VERSION = $( shell git describe --exact-match --tags $( CUR_SHA) 2>/dev/null || echo $( CUR_BRANCH) -$( CUR_SHA) ) # use by golang flags
PKG_VERSION = $( VERSION) # used for package name
# Go build command and environment variables for target OS and architecture
GOVERSION = 1.24
GO = container # container, local
OUTPUT = katenary
GOOS = linux
GOARCH = amd64
CGO_ENABLED = 0
PREFIX = ~/.local
BLD_CMD = go build -ldflags= " -X 'katenary/generator.Version= $( VERSION) ' " -o $( OUTPUT) ./cmd/katenary
2025-07-07 21:58:15 +02:00
2025-07-10 08:13:49 +02:00
# Get the container (podman is preferred, but docker is also supported)
2025-07-07 21:58:15 +02:00
# TODO: prpose nerdctl
2021-12-01 09:09:30 +01:00
CTN := $( shell which podman 2>& 1 1>/dev/null && echo "podman" || echo "docker" )
2025-07-07 21:58:15 +02:00
2025-07-10 08:13:49 +02:00
# Packaging OCI image, to build rpm, deb, pacman, tar packages
PKG_OCI_IMAGE = packaging:fedora
PKG_OCI_OPTS := --rm -it \
-w $$ PKG_OCI_WDIR \
-v ./:/opt/katenary:z \
--userns keep-id:uid= 999,gid= 999 \
$( PKG_OCI_IMAGE)
# Set the version and package version, following build mode (default, release)
2025-07-07 21:58:15 +02:00
MODE = default
2024-11-26 16:47:37 +01:00
RELEASE = ""
2025-07-10 08:13:49 +02:00
# If release mode
2025-07-07 21:58:15 +02:00
i f e q ( $( MODE ) , r e l e a s e )
2025-07-10 08:13:49 +02:00
PKG_VERSION = v$( VERSION)
2025-07-07 21:58:15 +02:00
VERSION:= release-$( VERSION)
e n d i f
2025-07-10 08:13:49 +02:00
# UPX compression
2025-07-07 21:58:15 +02:00
UPX_OPTS =
2025-06-15 16:02:45 +02:00
UPX ?= upx $( UPX_OPTS)
2023-12-06 15:24:02 +01:00
2025-07-07 17:59:16 +02:00
BUILD_IMAGE = docker.io/golang:$( GOVERSION)
2023-12-06 15:24:02 +01:00
# List of source files
2025-07-10 08:13:49 +02:00
SOURCES = $( shell find -name "*.go" -or -name "*.tpl" -type f | grep -v -P "^./example|^./vendor" )
2023-12-06 15:24:02 +01:00
# List of binaries to build and sign
BINARIES = dist/katenary-linux-amd64 dist/katenary-linux-arm64 dist/katenary.exe dist/katenary-darwin-amd64 dist/katenary-freebsd-amd64 dist/katenary-freebsd-arm64
2025-07-07 21:58:15 +02:00
BINARIES += dist/katenary-windows-setup.exe
2025-07-10 08:13:49 +02:00
## GPG
2023-12-06 15:24:02 +01:00
# List of signatures to build
ASC_BINARIES = $( patsubst %,%.asc,$( BINARIES) )
2025-07-10 08:13:49 +02:00
# GPG signer
SIGNER = metal3d@gmail.com
2023-12-06 15:24:02 +01:00
2025-07-10 08:13:49 +02:00
# Browser command to see coverage report after tests
2024-10-17 17:08:42 +02:00
BROWSER = $( shell command -v epiphany || echo xdg-open)
2022-02-16 18:32:51 +01:00
2023-12-06 15:24:02 +01:00
all : build
2022-01-26 09:43:01 +01:00
2021-12-01 09:09:30 +01:00
help :
2023-12-06 15:24:02 +01:00
@cat <<EOF | fold -s -w 80
2021-12-01 09:09:30 +01:00
= = = HELP = = =
To avoid you to install Go, the build is made by podman or docker.
2023-12-06 15:24:02 +01:00
Installinf ( you can use local Go by setting GO = local ) ) :
# use podman or docker to build
2021-12-01 09:09:30 +01:00
$$ make install
2023-12-06 15:24:02 +01:00
# or use local Go
$$ make install GO = local
2021-12-01 09:09:30 +01:00
This will build and install katenary inside the PREFIX( /bin) value ( default is $( PREFIX) )
2023-12-06 15:24:02 +01:00
To change the PREFIX to somewhere where only root or sudo users can save the binary, it is recommended to build before install, one more time you can use local Go by setting GO = local:
2021-12-01 09:09:30 +01:00
$$ make build
$$ sudo make install PREFIX = /usr/local
2022-02-16 18:32:51 +01:00
Katenary is statically built ( in Go) , so there is no library to install.
To build for others OS:
2022-03-31 14:12:20 +02:00
$$ make build GOOS = linux GOARCH = amd64
2022-02-16 18:32:51 +01:00
This will build the binary for linux amd64.
2022-03-31 14:12:20 +02:00
$$ make build GOOS = linux GOARCH = arm
2022-02-16 18:32:51 +01:00
This will build the binary for linux arm.
2022-03-31 14:12:20 +02:00
$$ make build GOOS = windows GOARCH = amd64
2022-02-16 18:32:51 +01:00
This will build the binary for windows amd64.
2022-03-31 14:12:20 +02:00
$$ make build GOOS = darwin GOARCH = amd64
2022-02-16 18:32:51 +01:00
This will build the binary for darwin amd64.
2022-03-31 14:12:20 +02:00
2022-02-16 18:32:51 +01:00
Or you can build all versions:
$$ make build-all
2021-12-01 09:09:30 +01:00
EOF
2022-04-01 10:47:58 +02:00
2025-07-07 21:58:15 +02:00
## BUILD
2025-07-10 08:13:49 +02:00
# Simply build the binary for the current OS and architecture
2023-12-06 15:24:02 +01:00
build : pull katenary
2022-02-16 18:32:51 +01:00
pull :
2022-03-31 14:12:20 +02:00
i f n e q ( $( GO ) , l o c a l )
2022-02-16 18:32:51 +01:00
@echo -e " \033[1;32mPulling $( BUILD_IMAGE) docker image\033[0m "
@$( CTN) pull $( BUILD_IMAGE)
2022-03-31 14:12:20 +02:00
e n d i f
2022-02-16 18:32:51 +01:00
2023-12-06 15:24:02 +01:00
katenary : $( SOURCES ) Makefile go .mod go .sum
i f e q ( $( GO ) , l o c a l )
@echo "=> Build on host using go"
$( BLD_CMD)
e l s e i f e q ( $( CTN ) , p o d m a n )
2025-07-07 13:47:27 +02:00
@echo "=> Build in container using" $( CTN)
2025-07-07 21:58:15 +02:00
@podman run -e CGO_ENABLED = $( CGO_ENABLED) -e GOOS = $( GOOS) -e GOARCH = $( GOARCH) \
2025-06-15 16:01:16 +02:00
--rm -v $( PWD) :/go/src/katenary:z -w /go/src/katenary --userns keep-id $( BUILD_IMAGE) $( BLD_CMD)
2023-12-06 15:24:02 +01:00
e l s e
2025-07-07 13:47:27 +02:00
@echo "=> Build in container using" $( CTN)
@docker run -e CGO_ENABLED = $( CGO_ENABLED) -e GOOS = $( GOOS) -e GOARCH = $( GOARCH) \
2025-06-15 16:01:16 +02:00
--rm -v $( PWD) :/go/src/katenary:z -w /go/src/katenary --user $( shell id -u) :$( shell id -g) -e HOME = /tmp $( BUILD_IMAGE) $( BLD_CMD)
2023-12-06 15:24:02 +01:00
e n d i f
2025-07-07 21:58:15 +02:00
# Make dist, build executables for all platforms, sign them, and compress them with upx if possible.
# Also generate the windows installer.
2025-07-10 08:13:49 +02:00
dist : prepare $( BINARIES ) upx gpg -sign check -sign packages
2023-12-06 15:24:02 +01:00
prepare : pull
2022-02-16 18:32:51 +01:00
mkdir -p dist
2025-07-10 08:13:49 +02:00
dist/katenary-linux-amd64 : $( SOURCES ) Makefile go .mod go .sum
2022-03-31 14:12:20 +02:00
@echo
@echo -e " \033[1;32mBuilding katenary $( VERSION) for linux-amd64...\033[0m "
2025-07-10 08:13:49 +02:00
$( MAKE) katenary GOOS = linux GOARCH = amd64 OUTPUT = $@
2025-07-07 13:47:27 +02:00
strip $@
2022-02-16 18:32:51 +01:00
2025-07-10 08:13:49 +02:00
dist/katenary-linux-arm64 : $( SOURCES ) Makefile go .mod go .sum
2022-03-31 14:12:20 +02:00
@echo
@echo -e " \033[1;32mBuilding katenary $( VERSION) for linux-arm...\033[0m "
2025-07-10 08:13:49 +02:00
$( MAKE) katenary GOOS = linux GOARCH = arm64 OUTPUT = $@
2022-02-16 18:32:51 +01:00
2025-07-10 08:13:49 +02:00
dist/katenary.exe : $( SOURCES ) Makefile go .mod go .sum
2022-03-31 14:12:20 +02:00
@echo
@echo -e " \033[1;32mBuilding katenary $( VERSION) for windows...\033[0m "
2025-07-10 08:13:49 +02:00
$( MAKE) katenary GOOS = windows GOARCH = amd64 OUTPUT = $@
2022-02-16 18:32:51 +01:00
2025-07-10 08:13:49 +02:00
dist/katenary-darwin-amd64 : $( SOURCES ) Makefile go .mod go .sum
2022-03-31 14:12:20 +02:00
@echo
@echo -e " \033[1;32mBuilding katenary $( VERSION) for darwin...\033[0m "
2025-07-10 08:13:49 +02:00
$( MAKE) katenary GOOS = darwin GOARCH = amd64 OUTPUT = $@
2022-03-31 14:12:20 +02:00
2025-07-10 08:13:49 +02:00
dist/katenary-freebsd-amd64 : $( SOURCES ) Makefile go .mod go .sum
2022-03-31 14:12:20 +02:00
@echo
@echo -e " \033[1;32mBuilding katenary $( VERSION) for freebsd...\033[0m "
2025-07-10 08:13:49 +02:00
$( MAKE) katenary GOOS = freebsd GOARCH = amd64 OUTPUT = $@
2025-07-07 13:47:27 +02:00
strip $@
2022-03-31 14:12:20 +02:00
2025-07-10 08:13:49 +02:00
dist/katenary-freebsd-arm64 : $( SOURCES ) Makefile go .mod go .sum
2022-03-31 14:12:20 +02:00
@echo
@echo -e " \033[1;32mBuilding katenary $( VERSION) for freebsd-arm64...\033[0m "
2025-07-10 08:13:49 +02:00
$( MAKE) katenary GOOS = freebsd GOARCH = arm64 OUTPUT = $@
2025-07-07 13:47:27 +02:00
2025-07-10 08:13:49 +02:00
dist/katenary-windows-setup.exe : nsis /EnVar .dll dist /katenary .exe packager -oci -image $( SOURCES ) Makefile go .mod go .sum
PKG_OCI_WDIR = /opt/katenary
podman run $( PKG_OCI_OPTS) \
makensis -DAPP_VERSION= $( VERSION) nsis/katenary.nsi
2025-07-07 21:58:15 +02:00
mv nsis/katenary-windows-setup.exe dist/katenary-windows-setup.exe
2025-07-07 17:58:21 +02:00
2025-07-10 08:13:49 +02:00
# Download the EnVar plugin for NSIS, put it in the nsis directory, and clean up
2025-07-07 17:58:21 +02:00
nsis/EnVar.dll :
curl https://nsis.sourceforge.io/mediawiki/images/7/7f/EnVar_plugin.zip -o nsis/EnVar_plugin.zip
cd nsis
unzip -o EnVar_plugin.zip Plugins/x86-unicode/EnVar.dll
mv Plugins/x86-unicode/EnVar.dll EnVar.dll
rm -rf EnVar_plugin.zip Plugins
2025-07-10 08:13:49 +02:00
upx : dist /katenary -linux -amd 64 dist /katenary -linux -arm 64 dist /katenary -darwin -amd 64
2025-07-07 21:58:15 +02:00
$( UPX) dist/katenary-linux-amd64
$( UPX) dist/katenary-linux-arm64
#$(UPX) dist/katenary.exe
$( UPX) dist/katenary-darwin-amd64 --force-macos
2025-07-10 08:13:49 +02:00
## Linux / FreeBSD packages
DESCRIPTION := $( shell cat packaging/description | sed ':a;N;$$!ba;s/\n/\\n/g' )
FPM_OPTS = --name katenary \
--version $( PKG_VERSION) \
--url https://katenary.org \
--vendor "Katenary Project" \
--maintainer "Patrice Ferlet <metal3d@gmail.com>" \
--license "MIT" \
--description= " $$ (printf " $( DESCRIPTION) " | fold -s)"
FPM_COMMON_FILES = ../doc/share/man/man1/katenary.1= /usr/local/share/man/man1/katenary.1 \
../LICENSE= /usr/local/share/doc/katenary/LICENSE \
../README.md= /usr/local/share/doc/katenary/README.md \
packages : manpage packager -oci -image
@PKG_OCI_WDIR= /opt/katenary/dist
for arch in amd64 arm64; do \
for target in rpm deb pacman tar; do \
echo " ==> Building $$ target package for arch $$ arch... " ; \
podman run $( PKG_OCI_OPTS) fpm -s dir -t $$ target -a $$ arch -f $( FPM_OPTS) \
$( FPM_COMMON_FILES) \
./katenary-linux-$$ arch = /usr/local/bin/katenary; \
done
mv dist/katenary.tar dist/katenary-linux-$( PKG_VERSION) .$$ arch.tar
for target in freebsd tar; do \
echo " ==> Building $$ target package for arch $$ arch " ; \
podman run $( PKG_OCI_OPTS) fpm -s dir -t $$ target -a $$ arch -f $( FPM_OPTS) \
$( FPM_COMMON_FILES) \
./katenary-freebsd-$$ arch = /usr/local/bin/katenary;
done
mv dist/katenary-$( PKG_VERSION) .txz dist/katenary-$( PKG_VERSION) .$$ arch.txz
mv dist/katenary.tar dist/katenary-freebsd-$( PKG_VERSION) .$$ arch.tar
done
packager-oci-image :
@podman build -t packaging:fedora ./packaging/oci 1>/dev/null
2025-07-07 21:58:15 +02:00
## GPG signing
2025-07-07 17:58:21 +02:00
2023-12-06 15:24:02 +01:00
gpg-sign :
rm -f dist/*.asc
$( MAKE) $( ASC_BINARIES)
2021-12-01 08:32:30 +01:00
2025-07-07 21:58:15 +02:00
check-sign :
@echo "=> Checking signatures..."
@for f in $( ASC_BINARIES) ; do \
if gpg --verify $$ f & >/dev/null; then \
echo " Signature for $$ f is valid " ; \
else \
echo " Signature for $$ f is invalid " ; \
exit 1; \
fi ; \
done
2023-12-06 15:24:02 +01:00
dist/%.asc : dist /%
gpg --armor --detach-sign --default-key $( SIGNER) $< & >/dev/null || exit 1
2021-12-01 08:32:30 +01:00
2025-06-15 16:02:45 +02:00
2025-07-07 21:58:15 +02:00
## installation and uninstallation
2025-06-15 16:02:45 +02:00
2021-12-01 09:09:30 +01:00
install : build
2023-12-06 15:24:02 +01:00
install -Dm755 katenary $( PREFIX) /bin/katenary
2021-12-01 09:09:30 +01:00
uninstall :
rm -f $( PREFIX) /bin/katenary
2022-03-31 14:12:20 +02:00
2024-04-10 04:51:45 +02:00
serve-doc : __label_doc
@cd doc && \
[ -d venv ] || python -m venv venv; \
source venv/bin/activate && \
echo "==> Installing requirements in the virtual env..."
pip install -qq -r requirements.txt && \
echo "==> Serving doc with mkdocs..." && \
mkdocs serve
2025-07-07 21:58:15 +02:00
## Documentation generation
2023-12-06 15:24:02 +01:00
2025-06-15 14:48:24 +02:00
doc :
@echo "=> Generating documentation..."
# generate the labels doc and code doc
$( MAKE) __label_doc
2025-07-09 14:11:46 +02:00
manpage :
@echo "=> Generating manpage from documentation"
@cd doc && \
[ -d venv ] || python -m venv venv; \
source venv/bin/activate && \
echo "==> Installing requirements in the virtual env..." && \
pip install -qq -r requirements.txt && \
pip install -qq -r manpage_requirements.txt && \
echo "==> Generating manpage..." && \
MANPAGE = true mkdocs build && \
rm -rf site &&
echo "==> Manpage generated in doc/share/man/man1/katenary.1"
2025-07-07 21:58:15 +02:00
install-gomarkdoc :
go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest
2023-12-06 15:24:02 +01:00
__label_doc :
2024-04-10 04:51:45 +02:00
@command -v gomarkdoc || ( echo "==> We need to install gomarkdoc..." && \
2025-07-07 21:58:15 +02:00
$( MAKE) install-gomarkdoc)
2023-12-06 15:24:02 +01:00
@echo "=> Generating labels doc..."
# short label doc
go run ./cmd/katenary help-labels -m | \
sed -i '
/START_LABEL_DOC/,/STOP_LABEL_DOC/{ /<!--/!d} ;
/START_LABEL_DOC/,/STOP_LABEL_DOC/r/dev/stdin
' doc/docs/labels.md
# detailed label doc
go run ./cmd/katenary help-labels -am | sed 's/^##/###/' | \
sed -i '
/START_DETAILED_DOC/,/STOP_DETAILED_DOC/{ /<!--/!d} ;
/START_DETAILED_DOC/,/STOP_DETAILED_DOC/r/dev/stdin
' doc/docs/labels.md
echo "=> Generating Code documentation..."
PACKAGES = $$ ( for f in $$ ( find . -name "*.go" -type f) ; do dirname $$ f; done | sort -u)
for pack in $$ PACKAGES; do
echo " -> Generating doc for $$ pack "
2024-04-10 04:51:45 +02:00
gomarkdoc --repository.default-branch $( shell git branch --show-current) -o doc/docs/packages/$$ pack.md $$ pack
2023-12-06 15:24:02 +01:00
sed -i '/^## Index/,/^##/ { /## Index/d; /^##/! d }' doc/docs/packages/$$ pack.md
done
2025-07-06 10:52:56 +02:00
2025-07-07 21:58:15 +02:00
## TESTS, security analysis, and code quality
2025-07-06 10:52:56 +02:00
# Scan the source code.
# - we don't need detection of text/template as it's not a web application, and
# - we don't need sha1 detection as it is not used for cryptographic purposes.
# Note: metrics are actually not sent to anyone - it's a thing that is removed from the code in the future.
sast :
opengrep \
--config auto \
--exclude-rule go.lang.security.audit.xss.import-text-template.import-text-template \
--exclude-rule go.lang.security.audit.crypto.use_of_weak_crypto.use-of-sha1 \
--metrics= on \
.
2025-07-07 21:58:15 +02:00
test :
@echo -e " \033[1;33mTesting katenary $( VERSION) ...\033[0m "
go test -coverprofile= cover.out ./...
$( MAKE) cover
cover :
go tool cover -func= cover.out | grep "total:"
go tool cover -html= cover.out -o cover.html
if [ " $( BROWSER) " = "xdg-open" ] ; then
xdg-open cover.html
else
$( BROWSER) -i --new-window cover.html
fi
## Miscellaneous
dist-clean :
rm -rf dist
rm -f katenary