-
-
Notifications
You must be signed in to change notification settings - Fork 61
Expand file tree
/
Copy pathMakefile
More file actions
432 lines (358 loc) · 15.6 KB
/
Makefile
File metadata and controls
432 lines (358 loc) · 15.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
#
# Makefile for resticprofile
#
GOCMD=$(shell command -v go)
GOBUILD=$(GOCMD) build
GOINSTALL=$(GOCMD) install
GORUN=$(GOCMD) run
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOTOOL=$(GOCMD) tool
GOMOD=$(GOCMD) mod
GOGENERATE=$(GOCMD) generate
GOPATH=$(shell $(GOCMD) env GOPATH)
GOBIN=$(shell $(GOCMD) env GOBIN)
ifeq ($(GOBIN),)
GOBIN := $(GOPATH)/bin
endif
BINARY=resticprofile
BINARY_DARWIN_AMD64=$(BINARY)_darwin
BINARY_DARWIN_ARM64=$(BINARY)_darwin_arm64
BINARY_LINUX_AMD64=$(BINARY)_linux
BINARY_LINUX_ARM64=$(BINARY)_linux_arm64
BINARY_PI=$(BINARY)_pi
BINARY_WINDOWS_AMD64=$(BINARY).exe
BINARY_WINDOWS_ARM64=$(BINARY)_arm64.exe
README=README.md
TESTS?=./...
COVERAGE_FILE=coverage.out
COVERAGE_SSH_FILE=coverage-ssh.out
JUNIT_FILE=unit-tests.xml
BUILD?=$(realpath build)/
RESTIC_GEN=$(BUILD)restic-generator
RESTIC_DIR=$(BUILD)restic-
RESTIC_CMD=$(BUILD)restic-commands.json
JSONSCHEMA_DIR=docs/static/jsonschema
CONFIG_REFERENCE_DIR=docs/content/reference
BUILD_DATE=`date`
BUILD_COMMIT=`git rev-parse HEAD`
CURRENT_DIR = $(shell pwd)
TMP_MOUNT_LINUX=/tmp/backup
TMP_MOUNT_DARWIN=/Volumes/RAMDisk
TMP_MOUNT=
UNAME := $(shell uname -s)
ifeq ($(UNAME),Linux)
TMP_MOUNT=${TMP_MOUNT_LINUX}
endif
ifeq ($(UNAME),Darwin)
TMP_MOUNT=${TMP_MOUNT_DARWIN}
endif
TMPDIR ?= /tmp
SSH_TESTS_TMPDIR=$(shell echo "$(TMPDIR)/resticprofile-ssh-tests" | tr -s /)
TOC_START=<\!--ts-->
TOC_END=<\!--te-->
TOC_PATH=toc.md
# Default target
.PHONY: help
help: ## Show the help
@echo "Usage: make <target>"
@echo
@echo "Targets:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-26s\033[0m %s\n", $$1, $$2}'
@echo
all: prepare_test test build
.PHONY: test test-ci coverage
.PHONY: download download-restic-key
.PHONY: build build-mac build-linux build-pi build-windows build-no-selfupdate build-all
.PHONY: generate-config-reference generate-jsonschema generate-install generate-restic
.PHONY: all verify prepare_test prepare_build install clean ramdisk rest-server nightly toc syslog checkdoc
verify: ## Verify go installation
ifeq ($(GOPATH),)
@echo "GOPATH not found, please check your go installation"
exit 1
endif
$(GOBIN)/eget: verify
@echo "[*] $@"
GOBIN="$(GOBIN)" $(GOCMD) install -v github.com/zyedidia/[email protected]
$(GOBIN)/goreleaser: verify $(GOBIN)/eget
@echo "[*] $@"
"$(GOBIN)/eget" goreleaser/goreleaser --upgrade-only --to '$(GOBIN)'
$(GOBIN)/github-markdown-toc.go: verify $(GOBIN)/eget
@echo "[*] $@"
"$(GOBIN)/eget" ekalinin/github-markdown-toc.go --upgrade-only --file gh-md-toc --to '$(GOBIN)'
$(GOBIN)/mockery: verify $(GOBIN)/eget
@echo "[*] $@"
"$(GOBIN)/eget" vektra/mockery --tag v3.7.0 --upgrade-only --to '$(GOBIN)'
$(GOBIN)/golangci-lint-v2: verify $(GOBIN)/eget
@echo "[*] $@"
"$(GOBIN)/eget" golangci/golangci-lint --tag v2.11.4 --asset=tar.gz --upgrade-only --to '$(GOBIN)/golangci-lint-v2'
$(GOBIN)/hugo: $(GOBIN)/eget
@echo "[*] $@"
"$(GOBIN)/eget" gohugoio/hugo --tag v0.150.1 --upgrade-only --asset=extended_0 --to '$(GOBIN)'
$(GOBIN)/muffet: verify $(GOBIN)/eget
@echo "[*] $@"
"$(GOBIN)/eget" raviqqe/muffet --upgrade-only --to '$(GOBIN)'
$(GOBIN)/gotestsum: verify $(GOBIN)/eget
@echo "[*] $@"
"$(GOBIN)/eget" gotestyourself/gotestsum --upgrade-only --to '$(GOBIN)'
prepare_build: verify download
@echo "[*] $@"
prepare_test: verify download $(GOBIN)/mockery ## Generate mocks
@echo "[*] $@"
@find . -path "*/mocks/*" -exec rm {} \;
@"$(GOBIN)/mockery" --config .mockery.yml
$(BUILD)test-args: ./testhelpers/args/*.go ## Build the test-args binary
@echo "[*] $@"
@$(GOBUILD) -v -o $(BUILD)test-args ./testhelpers/args
$(BUILD)test-echo: ./testhelpers/echo/*.go ## Build the test-echo binary
@echo "[*] $@"
@$(GOBUILD) -v -o $(BUILD)test-echo ./testhelpers/echo
$(BUILD)test-crontab: ./testhelpers/crontab/*.go ## Build the test-crontab binary
@echo "[*] $@"
@$(GOBUILD) -v -o $(BUILD)test-crontab ./testhelpers/crontab
$(BUILD)test-shell: ./testhelpers/shell/*.go ## Build the test-shell binary
@echo "[*] $@"
@$(GOBUILD) -v -o $(BUILD)test-shell ./testhelpers/shell
.PHONY: test-helpers
test-helpers: $(BUILD)test-args $(BUILD)test-echo $(BUILD)test-crontab $(BUILD)test-shell ## Build all test helper binaries
download: verify ## Download dependencies
@echo "[*] $@"
GOPATH="$(GOPATH)" \
$(GOMOD) download
download-restic-key: ## Download restic GPG key
@echo "[*] $@"
KEY_FILE=$(abspath restic/gpg-key.asc)
curl https://restic.net/gpg-key-alex.asc > $(KEY_FILE)
install: prepare_build ## Install the binary (to $GOBIN)
@echo "[*] $@"
GOBIN="$(GOBIN)" \
$(GOINSTALL) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
build: prepare_build ## Build the binary
@echo "[*] $@"
GOPATH="$(GOPATH)" \
$(GOBUILD) -o $(BINARY) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
build-no-selfupdate: prepare_build ## Build the binary without self-update feature
@echo "[*] $@"
GOPATH="$(GOPATH)" \
$(GOBUILD) -o $(BINARY) -v -tags no_self_update -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
build-mac: prepare_build ## Build the binary for macOS
@echo "[*] $@"
GOPATH="$(GOPATH)" \
GOOS="darwin" GOARCH="amd64" $(GOBUILD) -o $(BINARY_DARWIN_AMD64) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
GOPATH="$(GOPATH)" \
GOOS="darwin" GOARCH="arm64" $(GOBUILD) -o $(BINARY_DARWIN_ARM64) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
build-linux: prepare_build ## Build the binary for Linux
@echo "[*] $@"
GOPATH="$(GOPATH)" \
GOOS="linux" GOARCH="amd64" $(GOBUILD) -o $(BINARY_LINUX_AMD64) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
GOPATH="$(GOPATH)" \
GOOS="linux" GOARCH="arm64" $(GOBUILD) -o $(BINARY_LINUX_ARM64) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
build-pi: prepare_build ## Build the binary for Raspberry Pi (armv6)
@echo "[*] $@"
GOPATH="$(GOPATH)" \
GOOS="linux" GOARCH="arm" GOARM="6" $(GOBUILD) -o $(BINARY_PI) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
build-windows: prepare_build ## Build the binary for Windows
@echo "[*] $@"
GOPATH="$(GOPATH)" \
GOOS="windows" GOARCH="amd64" $(GOBUILD) -o $(BINARY_WINDOWS_AMD64) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
GOPATH="$(GOPATH)" \
GOOS="windows" GOARCH="arm64" $(GOBUILD) -o $(BINARY_WINDOWS_ARM64) -v -ldflags "-X 'main.commit=${BUILD_COMMIT}' -X 'main.date=${BUILD_DATE}' -X 'main.builtBy=make'"
build-all: build-mac build-linux build-pi build-windows ## Build the binary for all platforms
test: export TEST_HELPERS=$(BUILD)
test: $(GOBIN)/gotestsum prepare_test test-helpers ## Run unit tests
@echo "[*] $@"
@$(GOBIN)/gotestsum -- -count=1 $(TESTS)
test-short: export TEST_HELPERS=$(BUILD)
test-short: $(GOBIN)/gotestsum prepare_test test-helpers ## Run unit tests in short mode
@echo "[*] $@"
@$(GOBIN)/gotestsum -- -short -count=1 $(TESTS)
test-race: export TEST_HELPERS=$(BUILD)
test-race: $(GOBIN)/gotestsum prepare_test test-helpers ## Run unit tests with race detector
@echo "[*] $@"
@$(GOBIN)/gotestsum -- -short -race -count=1 $(TESTS)
test-ci: export TEST_HELPERS=$(BUILD)
test-ci: $(GOBIN)/gotestsum prepare_test test-helpers ## Run unit tests with coverage (for CI)
@echo "[*] $@"
@$(GOGENERATE) ./...
@$(GOBIN)/gotestsum --junitfile $(JUNIT_FILE) -- -race -short -count=1 -tags=fuse -coverprofile='$(COVERAGE_FILE)' ./...
coverage: ## Generate coverage report
@echo "[*] $@"
$(GOTEST) -coverprofile=$(COVERAGE_FILE) $(TESTS)
$(GOTOOL) cover -html=$(COVERAGE_FILE)
clean: ## Clean up the build artifacts
@echo "[*] $@"
$(GOCLEAN)
rm -rf \
$(BINARY) \
$(BINARY_DARWIN_AMD64) \
$(BINARY_DARWIN_ARM64) \
$(BINARY_LINUX_AMD64) \
$(BINARY_LINUX_ARM64) \
$(BINARY_PI) \
$(BINARY_WINDOWS_AMD64) \
$(BINARY_WINDOWS_ARM64) \
$(COVERAGE_FILE) \
$(COVERAGE_SSH_FILE) \
$(JUNIT_FILE) \
restic_*_linux_amd64* \
${BUILD}restic* \
${BUILD}rclone* \
${BUILD}test* \
*.test \
*.log \
*.out \
*.xml \
dist/*
find . -path "*/mocks/*" -exec rm {} \;
restic cache --cleanup
ramdisk: ${TMP_MOUNT} ## Create a ramdisk for testing
# Fixed size ramdisk for mac OS X
${TMP_MOUNT_DARWIN}:
# blocks = 512B so it's creating a 2GB fixed size disk image
diskutil erasevolume HFS+ RAMDisk `hdiutil attach -nomount ram://4194304`
# Mount tmpfs on linux
${TMP_MOUNT_LINUX}:
mkdir -p ${TMP_MOUNT_LINUX}
sudo mount -t tmpfs -o "rw,relatime,size=2097152k,uid=`id -u`,gid=`id -g`" tmpfs ${TMP_MOUNT_LINUX}
rest-server: ## Run rest-server docker container for testing
@echo "[*] $@"
REST_IMAGE=restic/rest-server
REST_CONTAINER=rest_server
REST_DATA=/tmp/restic
REST_OPTIONS=""
docker pull ${REST_IMAGE}
docker run -d -p 8000:8000 -v ${REST_DATA}:/data --name ${REST_CONTAINER} --restart always -e "OPTIONS=${REST_OPTIONS}" ${REST_IMAGE}
nightly: $(GOBIN)/goreleaser ## Create a nightly release (for testing goreleaser setup)
@echo "[*] $@"
GITLAB_TOKEN= goreleaser --snapshot --skip=publish --clean
toc: $(GOBIN)/github-markdown-toc.go
@echo "[*] $@"
cat ${README} | gh-md-toc --hide-footer > ${TOC_PATH}
sed -i ".1" "/${TOC_START}/,/${TOC_END}/{//!d;}" "${README}"
sed -i ".2" "/${TOC_START}/r ${TOC_PATH}" "${README}"
rm ${README}.1 ${README}.2 ${TOC_PATH}
generate-install: ## Generate the install script using godownloader
@echo "[*] $@"
godownloader .godownloader.yml -r creativeprojects/resticprofile -o install.sh
generate-restic: ## Generate the restic commands JSON file
@echo "[*] $@"
$(GOBUILD) -o $(RESTIC_GEN) $(abspath restic/generator)
rm $(RESTIC_CMD) || echo "clean $(RESTIC_CMD)"
$(RESTIC_GEN) --install $(RESTIC_DIR)0.9.4 --version=0.9.4 --base-version --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.10.0 --version=0.10.0 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.11.0 --version=0.11.0 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.12.0 --version=0.12.0 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.13.0 --version=0.13.0 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.14.0 --version=0.14.0 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.15.0 --version=0.15.0 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.16.0 --version=0.16.0 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.16.1 --version=0.16.1 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.16.4 --version=0.16.4 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.17.0 --version=0.17.0 --commands $(RESTIC_CMD)
$(RESTIC_GEN) --install $(RESTIC_DIR)0.18.0 --version=0.18.0 --commands $(RESTIC_CMD)
cp $(RESTIC_CMD) restic/commands.json
generate-jsonschema: build ## Generate the JSON schema files
@echo "[*] $@"
mkdir -p $(JSONSCHEMA_DIR) || echo "$(JSONSCHEMA_DIR) exists"
$(abspath $(BINARY)) generate --json-schema global > $(JSONSCHEMA_DIR)/config.json
for config_version in 1 2 ; do \
$(abspath $(BINARY)) generate --json-schema v$$config_version > $(JSONSCHEMA_DIR)/config-$$config_version.json ; \
for restic_version in 0.9 0.10 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 ; do \
name=$$(echo $$restic_version | sed 's/\./-/g') ; \
$(abspath $(BINARY)) generate --json-schema --version $$restic_version v$$config_version > $(JSONSCHEMA_DIR)/config-$$config_version-restic-$$name.json ; \
done ; \
done
generate-config-reference: build ## Generate the configuration reference documentation
@echo "[*] $@"
META_TITLE="Resticprofile configuration reference" \
META_WEIGHT="6" \
LAYOUT_NO_HEADLINE="1" \
LAYOUT_HEADINGS_START="#" \
LAYOUT_NOTICE_START='{{% notice style="note" %}}' \
LAYOUT_NOTICE_END="{{% /notice %}}" \
LAYOUT_HINT_START='{{% notice style="tip" %}}' \
LAYOUT_HINT_END="{{% /notice %}}" \
LAYOUT_UPLINK="[go to top](#reference)" \
$(abspath $(BINARY)) generate --config-reference --to $(CONFIG_REFERENCE_DIR)
.PHONY: documentation
documentation: generate-jsonschema generate-config-reference $(GOBIN)/hugo ## Generate the documentation site
@echo "[*] $@"
cd docs && hugo --minify
.PHONY: syslog-ng
syslog-ng: ## Run syslog-ng docker container for testing
@echo "[*] $@"
docker run -d \
--name=syslog-ng \
--rm \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Etc/UTC \
-p 5514:5514/udp \
-p 5514:6601/tcp \
-v $(CURRENT_DIR)/examples/syslog-ng:/config \
-v $(CURRENT_DIR)/log:/var/log \
lscr.io/linuxserver/syslog-ng:latest
checkdoc: ## Check documentation
@echo "[*] $@"
$(GOCMD) run ./config/checkdoc -r docs/content -i changelog.md
.PHONY: checklinks
checklinks: $(GOBIN)/muffet ## Check for broken links in the documentation site
@echo "[*] $@"
muffet --buffer-size=8192 --max-connections-per-host=8 --rate-limit=20 \
--exclude="(linux\.die\.net|scoop\.sh|stackoverflow\.com|commit)" \
--header="User-Agent: Muffet/$$(muffet --version)" \
http://127.0.0.1:1313/resticprofile/
.PHONY: lint
lint: $(GOBIN)/golangci-lint-v2 ## Run golangci-lint
@echo "[*] $@"
GOOS=darwin $(GOBIN)/golangci-lint-v2 run
GOOS=linux $(GOBIN)/golangci-lint-v2 run
GOOS=windows $(GOBIN)/golangci-lint-v2 run
.PHONY: fix
fix: $(GOBIN)/golangci-lint-v2 ## Run golangci-lint with --fix
@echo "[*] $@"
$(GOCMD) mod tidy
$(GOCMD) fix ./...
GOOS=darwin $(GOBIN)/golangci-lint-v2 run --fix
GOOS=linux $(GOBIN)/golangci-lint-v2 run --fix
GOOS=windows $(GOBIN)/golangci-lint-v2 run --fix
.PHONY: deploy-current
deploy-current: build-linux build-pi
@echo "[*] $@"
for server in $$(cat targets_amd64.txt); do \
echo "Deploying to $$server" ; \
rsync -avz --progress $(BINARY_LINUX_AMD64) $$server: ; \
ssh -t $$server "sudo -S install $(BINARY_LINUX_AMD64) /usr/local/bin/resticprofile" ; \
done
for server in $$(cat targets_armv6.txt); do \
echo "Deploying to $$server" ; \
rsync -avz --progress $(BINARY_PI) $$server: ; \
ssh -t $$server "sudo -S install $(BINARY_PI) /usr/local/bin/resticprofile" ; \
done
.PHONY: start-ssh-server
start-ssh-server: ## Start the SSH server for testing
@echo "[*] $@"
@mkdir -p $(SSH_TESTS_TMPDIR) && rm -f $(SSH_TESTS_TMPDIR)/id_* || echo "Failed to create temporary directory"
@ssh-keygen -t rsa -b 2048 -f $(SSH_TESTS_TMPDIR)/id_rsa -N "" -C "resticprofile@$(shell hostname)"
@ssh-keygen -t ecdsa -b 521 -f $(SSH_TESTS_TMPDIR)/id_ecdsa -N "" -C "resticprofile@$(shell hostname)"
@ssh-keygen -t ed25519 -f $(SSH_TESTS_TMPDIR)/id_ed25519 -N "" -C "resticprofile@$(shell hostname)"
@cd ./ssh/test && \
USER_ID=$(shell id -u) GROUP_ID=$(shell id -g) SSH_TESTS_TMPDIR=$(SSH_TESTS_TMPDIR) \
docker compose up -d --force-recreate
@sleep 1
@ssh-keyscan -p 2222 -H localhost > $(SSH_TESTS_TMPDIR)/known_hosts
.PHONY: stop-ssh-server
stop-ssh-server: ## Stop the SSH server and clean up temporary files
@echo "[*] $@"
cd ./ssh/test && SSH_TESTS_TMPDIR=$(SSH_TESTS_TMPDIR) docker compose down --remove-orphans
@test -d "$(SSH_TESTS_TMPDIR)" && rm -rf "$(SSH_TESTS_TMPDIR)" || echo "temporary directory not found, nothing to remove"
.PHONY: ssh-test
ssh-test: ## Run SSH client tests
@echo "[*] $@"
@go test -run TestSSHClient -v -race -tags ssh -coverprofile='$(COVERAGE_SSH_FILE)' ./ssh
.PHONY: compile-tests
compile-tests: export TEST_HELPERS=$(BUILD)
compile-tests: test-helpers ## Pre-compile all tests for running on BSD VMs
@echo "[*] $@"
@$(GOGENERATE) ./...
@$(GOTEST) -c . ./batt ./calendar ./config/... ./crond ./dial ./filesearch ./lock ./monitor ./priority ./remote ./restic ./schedule ./shell ./ssh ./term ./user ./util/...