1.PHONY: build package run stop run-client run-server run-haserver stop-haserver stop-client stop-server restart restart-server restart-client restart-haserver start-docker clean-dist clean nuke check-style check-client-style check-server-style check-unit-tests test dist prepare-enteprise run-client-tests setup-run-client-tests cleanup-run-client-tests test-client build-linux build-osx build-windows package-prep package-linux package-osx package-windows internal-test-web-client vet run-server-for-web-client-tests diff-config prepackaged-plugins prepackaged-binaries test-server test-server-ee test-server-quick test-server-race start-docker-check migrations-bindata new-migration migration-prereqs
2
3ROOT := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
4
5ifeq ($(OS),Windows_NT)
6	PLATFORM := Windows
7else
8	PLATFORM := $(shell uname)
9endif
10
11# Set an environment variable on Linux used to resolve `docker.host.internal` inconsistencies with
12# docker. This can be reworked once https://github.com/docker/for-linux/issues/264 is resolved
13# satisfactorily.
14ifeq ($(PLATFORM),Linux)
15	export IS_LINUX = -linux
16else
17	export IS_LINUX =
18endif
19
20IS_CI ?= false
21# Build Flags
22BUILD_NUMBER ?= $(BUILD_NUMBER:)
23BUILD_DATE = $(shell date -u)
24BUILD_HASH = $(shell git rev-parse HEAD)
25# If we don't set the build number it defaults to dev
26ifeq ($(BUILD_NUMBER),)
27	BUILD_NUMBER := dev
28endif
29BUILD_ENTERPRISE_DIR ?= ../enterprise
30BUILD_ENTERPRISE ?= true
31BUILD_ENTERPRISE_READY = false
32BUILD_TYPE_NAME = team
33BUILD_HASH_ENTERPRISE = none
34ifneq ($(wildcard $(BUILD_ENTERPRISE_DIR)/.),)
35	ifeq ($(BUILD_ENTERPRISE),true)
36		BUILD_ENTERPRISE_READY = true
37		BUILD_TYPE_NAME = enterprise
38		BUILD_HASH_ENTERPRISE = $(shell cd $(BUILD_ENTERPRISE_DIR) && git rev-parse HEAD)
39	else
40		BUILD_ENTERPRISE_READY = false
41		BUILD_TYPE_NAME = team
42	endif
43else
44	BUILD_ENTERPRISE_READY = false
45	BUILD_TYPE_NAME = team
46endif
47BUILD_WEBAPP_DIR ?= ../mattermost-webapp
48BUILD_CLIENT = false
49BUILD_HASH_CLIENT = independant
50ifneq ($(wildcard $(BUILD_WEBAPP_DIR)/.),)
51	ifeq ($(BUILD_CLIENT),true)
52		BUILD_CLIENT = true
53		BUILD_HASH_CLIENT = $(shell cd $(BUILD_WEBAPP_DIR) && git rev-parse HEAD)
54	else
55		BUILD_CLIENT = false
56	endif
57else
58	BUILD_CLIENT = false
59endif
60
61# We need current user's UID for `run-haserver` so docker compose does not run server
62# as root and mess up file permissions for devs. When running like this HOME will be blank
63# and docker will add '/', so we need to set the go-build cache location or we'll get
64# permission errors on build as it tries to create a cache in filesystem root.
65export CURRENT_UID = $(shell id -u):$(shell id -g)
66ifeq ($(HOME),/)
67	export XDG_CACHE_HOME = /tmp/go-cache/
68endif
69
70# Go Flags
71GOFLAGS ?= $(GOFLAGS:)
72# We need to export GOBIN to allow it to be set
73# for processes spawned from the Makefile
74export GOBIN ?= $(PWD)/bin
75GO=go
76DELVE=dlv
77LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildNumber=$(BUILD_NUMBER)"
78LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildDate=$(BUILD_DATE)"
79LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildHash=$(BUILD_HASH)"
80LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildHashEnterprise=$(BUILD_HASH_ENTERPRISE)"
81LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)"
82
83GO_MAJOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1)
84GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
85MINIMUM_SUPPORTED_GO_MAJOR_VERSION = 1
86MINIMUM_SUPPORTED_GO_MINOR_VERSION = 15
87GO_VERSION_VALIDATION_ERR_MSG = Golang version is not supported, please update to at least $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION).$(MINIMUM_SUPPORTED_GO_MINOR_VERSION)
88
89# GOOS/GOARCH of the build host, used to determine whether we're cross-compiling or not
90BUILDER_GOOS_GOARCH="$(shell $(GO) env GOOS)_$(shell $(GO) env GOARCH)"
91
92PLATFORM_FILES="./cmd/mattermost/main.go"
93
94# Output paths
95DIST_ROOT=dist
96DIST_PATH=$(DIST_ROOT)/mattermost
97DIST_PATH_LIN=$(DIST_ROOT)/linux/mattermost
98DIST_PATH_OSX=$(DIST_ROOT)/osx/mattermost
99DIST_PATH_WIN=$(DIST_ROOT)/windows/mattermost
100
101# Tests
102TESTS=.
103
104# Packages lists
105TE_PACKAGES=$(shell $(GO) list ./... | grep -v ./data)
106
107TEMPLATES_DIR=templates
108
109# Plugins Packages
110PLUGIN_PACKAGES ?= mattermost-plugin-antivirus-v0.1.2
111PLUGIN_PACKAGES += mattermost-plugin-autolink-v1.2.2
112PLUGIN_PACKAGES += mattermost-plugin-aws-SNS-v1.2.0
113PLUGIN_PACKAGES += mattermost-plugin-channel-export-v1.0.0
114PLUGIN_PACKAGES += mattermost-plugin-custom-attributes-v1.3.0
115PLUGIN_PACKAGES += mattermost-plugin-github-v2.0.1
116PLUGIN_PACKAGES += mattermost-plugin-gitlab-v1.3.0
117PLUGIN_PACKAGES += mattermost-plugin-playbooks-v1.20.2
118PLUGIN_PACKAGES += mattermost-plugin-jenkins-v1.1.0
119PLUGIN_PACKAGES += mattermost-plugin-jira-v2.4.0
120PLUGIN_PACKAGES += mattermost-plugin-nps-v1.1.0
121PLUGIN_PACKAGES += mattermost-plugin-welcomebot-v1.2.0
122PLUGIN_PACKAGES += mattermost-plugin-zoom-v1.5.0
123PLUGIN_PACKAGES += focalboard-v0.9.4
124
125# Prepares the enterprise build if exists. The IGNORE stuff is a hack to get the Makefile to execute the commands outside a target
126ifeq ($(BUILD_ENTERPRISE_READY),true)
127	IGNORE:=$(shell echo Enterprise build selected, preparing)
128	IGNORE:=$(shell rm -f imports/imports.go)
129	IGNORE:=$(shell cp $(BUILD_ENTERPRISE_DIR)/imports/imports.go imports/)
130	IGNORE:=$(shell rm -f enterprise)
131	IGNORE:=$(shell ln -s $(BUILD_ENTERPRISE_DIR) enterprise)
132else
133	IGNORE:=$(shell rm -f imports/imports.go)
134endif
135
136EE_PACKAGES=$(shell $(GO) list ./enterprise/...)
137
138ifeq ($(BUILD_ENTERPRISE_READY),true)
139ALL_PACKAGES=$(TE_PACKAGES) $(EE_PACKAGES)
140else
141ALL_PACKAGES=$(TE_PACKAGES)
142endif
143
144all: run ## Alias for 'run'.
145
146-include config.override.mk
147include config.mk
148include build/*.mk
149
150LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.MockCWS=$(MM_ENABLE_CWS_MOCK)"
151
152RUN_IN_BACKGROUND ?=
153ifeq ($(RUN_SERVER_IN_BACKGROUND),true)
154	RUN_IN_BACKGROUND := &
155endif
156
157start-docker-check:
158ifeq (,$(findstring minio,$(ENABLED_DOCKER_SERVICES)))
159  TEMP_DOCKER_SERVICES:=$(TEMP_DOCKER_SERVICES) minio
160endif
161ifeq ($(BUILD_ENTERPRISE_READY),true)
162  ifeq (,$(findstring openldap,$(ENABLED_DOCKER_SERVICES)))
163    TEMP_DOCKER_SERVICES:=$(TEMP_DOCKER_SERVICES) openldap
164  endif
165  ifeq (,$(findstring elasticsearch,$(ENABLED_DOCKER_SERVICES)))
166    TEMP_DOCKER_SERVICES:=$(TEMP_DOCKER_SERVICES) elasticsearch
167  endif
168endif
169ENABLED_DOCKER_SERVICES:=$(ENABLED_DOCKER_SERVICES) $(TEMP_DOCKER_SERVICES)
170
171start-docker: ## Starts the docker containers for local development.
172ifneq ($(IS_CI),false)
173	@echo CI Build: skipping docker start
174else ifeq ($(MM_NO_DOCKER),true)
175	@echo No Docker Enabled: skipping docker start
176else
177	@echo Starting docker containers
178
179	$(GO) run ./build/docker-compose-generator/main.go $(ENABLED_DOCKER_SERVICES) | docker-compose -f docker-compose.makefile.yml -f /dev/stdin run --rm start_dependencies
180ifneq (,$(findstring openldap,$(ENABLED_DOCKER_SERVICES)))
181	cat tests/${LDAP_DATA}-data.ldif | docker-compose -f docker-compose.makefile.yml exec -T openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest || true';
182endif
183ifneq (,$(findstring mysql-read-replica,$(ENABLED_DOCKER_SERVICES)))
184	./scripts/replica-mysql-config.sh
185endif
186endif
187
188run-haserver:
189ifeq ($(BUILD_ENTERPRISE_READY),true)
190	@echo Starting mattermost in an HA topology '(3 node cluster)'
191
192	docker-compose -f docker-compose.yaml up --remove-orphans haproxy
193endif
194
195stop-haserver:
196	@echo Stopping docker containers for HA topology
197	docker-compose stop
198
199stop-docker: ## Stops the docker containers for local development.
200ifeq ($(MM_NO_DOCKER),true)
201	@echo No Docker Enabled: skipping docker stop
202else
203	@echo Stopping docker containers
204
205	docker-compose stop
206endif
207
208clean-docker: ## Deletes the docker containers for local development.
209ifeq ($(MM_NO_DOCKER),true)
210	@echo No Docker Enabled: skipping docker clean
211else
212	@echo Removing docker containers
213
214	docker-compose down -v
215	docker-compose rm -v
216endif
217
218plugin-checker:
219	$(GO) run $(GOFLAGS) ./plugin/checker
220
221prepackaged-plugins: ## Populate the prepackaged-plugins directory
222	@echo Downloading prepackaged plugins
223	mkdir -p prepackaged_plugins
224	@cd prepackaged_plugins && for plugin_package in $(PLUGIN_PACKAGES) ; do \
225		curl -f -O -L https://plugins-store.test.mattermost.com/release/$$plugin_package.tar.gz; \
226		curl -f -O -L https://plugins-store.test.mattermost.com/release/$$plugin_package.tar.gz.sig; \
227	done
228
229prepackaged-binaries: ## Populate the prepackaged-binaries to the bin directory
230ifeq ($(shell test -f bin/mmctl && printf "yes"),yes)
231	@echo "MMCTL already exists in bin/mmctl not downloading a new version."
232else
233	@scripts/download_mmctl_release.sh
234endif
235
236golangci-lint: ## Run golangci-lint on codebase
237# https://stackoverflow.com/a/677212/1027058 (check if a command exists or not)
238	@if ! [ -x "$$(command -v golangci-lint)" ]; then \
239		echo "golangci-lint is not installed. Please see https://github.com/golangci/golangci-lint#install for installation instructions."; \
240		exit 1; \
241	fi; \
242
243	@echo Running golangci-lint
244	golangci-lint run ./...
245ifeq ($(BUILD_ENTERPRISE_READY),true)
246ifneq ($(MM_NO_ENTERPRISE_LINT),true)
247	golangci-lint run ./enterprise/...
248endif
249endif
250
251app-layers: ## Extract interface from App struct
252	$(GO) get -modfile=go.tools.mod github.com/reflog/struct2interface
253	$(GOBIN)/struct2interface -f "app" -o "app/app_iface.go" -p "app" -s "App" -i "AppIface" -t ./app/layer_generators/app_iface.go.tmpl
254	$(GO) run ./app/layer_generators -in ./app/app_iface.go -out ./app/opentracing/opentracing_layer.go -template ./app/layer_generators/opentracing_layer.go.tmpl
255
256i18n-extract: ## Extract strings for translation from the source code
257	$(GO) get -modfile=go.tools.mod github.com/mattermost/mattermost-utilities/mmgotool
258	$(GOBIN)/mmgotool i18n extract --portal-dir=""
259
260i18n-check: ## Exit on empty translation strings and translation source strings
261	$(GO) get -modfile=go.tools.mod github.com/mattermost/mattermost-utilities/mmgotool
262	$(GOBIN)/mmgotool i18n clean-empty --portal-dir="" --check
263	$(GOBIN)/mmgotool i18n check-empty-src --portal-dir=""
264
265store-mocks: ## Creates mock files.
266	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
267	$(GOBIN)/mockery -dir store -all -output store/storetest/mocks -note 'Regenerate this file using `make store-mocks`.'
268
269telemetry-mocks: ## Creates mock files.
270	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
271	$(GOBIN)/mockery -dir services/telemetry -all -output services/telemetry/mocks -note 'Regenerate this file using `make telemetry-mocks`.'
272
273store-layers: ## Generate layers for the store
274	$(GO) generate $(GOFLAGS) ./store
275
276migration-prereqs: ## Builds prerequisite packages for migrations
277	$(GO) get -modfile=go.tools.mod github.com/golang-migrate/migrate/v4/cmd/migrate
278
279new-migration: migration-prereqs ## Creates a new migration
280	@echo "Generating new migration for mysql"
281	$(GOBIN)/migrate create -ext sql -dir db/migrations/mysql -seq $(name)
282
283	@echo "Generating new migration for postgres"
284	$(GOBIN)/migrate create -ext sql -dir db/migrations/postgres -seq $(name)
285
286	@echo "When you are done writing your migration, run 'make migrations'"
287
288migrations-bindata: ## Generates bindata migrations
289	$(GO) get -modfile=go.tools.mod github.com/go-bindata/go-bindata/...
290
291	@echo Generating bindata for migrations
292	$(GO) generate $(GOFLAGS) ./db/migrations/
293
294filestore-mocks: ## Creates mock files.
295	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
296	$(GOBIN)/mockery -dir shared/filestore -all -output shared/filestore/mocks -note 'Regenerate this file using `make filestore-mocks`.'
297
298ldap-mocks: ## Creates mock files for ldap.
299	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
300	$(GOBIN)/mockery -dir enterprise/ldap -all -output enterprise/ldap/mocks -note 'Regenerate this file using `make ldap-mocks`.'
301
302plugin-mocks: ## Creates mock files for plugins.
303	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
304	$(GOBIN)/mockery -dir plugin -name API -output plugin/plugintest -outpkg plugintest -case underscore -note 'Regenerate this file using `make plugin-mocks`.'
305	$(GOBIN)/mockery -dir plugin -name Hooks -output plugin/plugintest -outpkg plugintest -case underscore -note 'Regenerate this file using `make plugin-mocks`.'
306	$(GOBIN)/mockery -dir plugin -name Driver -output plugin/plugintest -outpkg plugintest -case underscore -note 'Regenerate this file using `make plugin-mocks`.'
307
308einterfaces-mocks: ## Creates mock files for einterfaces.
309	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
310	$(GOBIN)/mockery -dir einterfaces -all -output einterfaces/mocks -note 'Regenerate this file using `make einterfaces-mocks`.'
311
312searchengine-mocks: ## Creates mock files for searchengines.
313	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
314	$(GOBIN)/mockery -dir services/searchengine -all -output services/searchengine/mocks -note 'Regenerate this file using `make searchengine-mocks`.'
315
316sharedchannel-mocks: ## Creates mock files for shared channels.
317	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
318	$(GOBIN)/mockery -dir=./services/sharedchannel -name=ServerIface -output=./services/sharedchannel -inpkg -outpkg=sharedchannel -testonly -note 'Regenerate this file using `make sharedchannel-mocks`.'
319	$(GOBIN)/mockery -dir=./services/sharedchannel -name=AppIface -output=./services/sharedchannel -inpkg -outpkg=sharedchannel -testonly -note 'Regenerate this file using `make sharedchannel-mocks`.'
320
321misc-mocks: ## Creates mocks for misc interfaces.
322	$(GO) get -modfile=go.tools.mod github.com/vektra/mockery/...
323	$(GOPATH)/bin/mockery -dir utils --name LicenseValidatorIface -output utils/mocks -note 'Regenerate this file using `make misc-mocks`.'
324
325pluginapi: ## Generates api and hooks glue code for plugins
326	$(GO) generate $(GOFLAGS) ./plugin
327
328check-prereqs: ## Checks prerequisite software status.
329	./scripts/prereq-check.sh
330
331check-prereqs-enterprise: ## Checks prerequisite software status for enterprise.
332ifeq ($(BUILD_ENTERPRISE_READY),true)
333	./scripts/prereq-check-enterprise.sh
334endif
335
336check-style: golangci-lint plugin-checker vet ## Runs style/lint checks
337
338
339do-cover-file: ## Creates the test coverage report file.
340	@echo "mode: count" > cover.out
341
342go-junit-report:
343	$(GO) get -modfile=go.tools.mod github.com/jstemmer/go-junit-report
344
345test-compile: ## Compile tests.
346	@echo COMPILE TESTS
347
348	for package in $(TE_PACKAGES) $(EE_PACKAGES); do \
349		$(GO) test $(GOFLAGS) -c $$package; \
350	done
351
352test-db-migration: start-docker ## Gets diff of upgrade vs new instance schemas.
353	./scripts/mysql-migration-test.sh 6.0
354	./scripts/psql-migration-test.sh 6.0
355
356test-db-migration-v5: start-docker ## Gets diff of upgrade vs new instance schemas.
357	./scripts/mysql-migration-v5-test.sh 5.0
358	./scripts/psql-migration-v5-test.sh 5.0
359
360gomodtidy:
361	@cp go.mod go.mod.orig
362	@cp go.sum go.sum.orig
363	$(GO) mod tidy
364	@if [ "$$(diff go.mod go.mod.orig)" != "" -o "$$(diff go.sum go.sum.orig)" != "" ]; then \
365		echo "go.mod/go.sum was modified. \ndiff- $$(diff go.mod go.mod.orig) \n$$(diff go.sum go.sum.orig) \nRun \"go mod tidy\"."; \
366		rm go.*.orig; \
367		exit 1; \
368	fi;
369	@rm go.*.orig;
370
371test-server-pre: check-prereqs-enterprise start-docker-check start-docker go-junit-report do-cover-file ## Runs tests.
372ifeq ($(BUILD_ENTERPRISE_READY),true)
373	@echo Running all tests
374else
375	@echo Running only TE tests
376endif
377
378test-server-race: test-server-pre
379	./scripts/test.sh "$(GO)" "-race $(GOFLAGS)" "$(ALL_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "90m" "atomic"
380  ifneq ($(IS_CI),true)
381    ifneq ($(MM_NO_DOCKER),true)
382      ifneq ($(TEMP_DOCKER_SERVICES),)
383	      @echo Stopping temporary docker services
384	      docker-compose stop $(TEMP_DOCKER_SERVICES)
385      endif
386    endif
387  endif
388
389test-server: test-server-pre
390	./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(ALL_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "45m" "count"
391  ifneq ($(IS_CI),true)
392    ifneq ($(MM_NO_DOCKER),true)
393      ifneq ($(TEMP_DOCKER_SERVICES),)
394	      @echo Stopping temporary docker services
395	      docker-compose stop $(TEMP_DOCKER_SERVICES)
396      endif
397    endif
398  endif
399
400test-server-ee: check-prereqs-enterprise start-docker-check start-docker go-junit-report do-cover-file ## Runs EE tests.
401	@echo Running only EE tests
402	./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(EE_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "20m" "count"
403
404test-server-quick: check-prereqs-enterprise ## Runs only quick tests.
405ifeq ($(BUILD_ENTERPRISE_READY),true)
406	@echo Running all tests
407	$(GO) test $(GOFLAGS) -short $(ALL_PACKAGES)
408else
409	@echo Running only TE tests
410	$(GO) test $(GOFLAGS) -short $(TE_PACKAGES)
411endif
412
413internal-test-web-client: ## Runs web client tests.
414	$(GO) run $(GOFLAGS) $(PLATFORM_FILES) test web_client_tests
415
416run-server-for-web-client-tests: ## Tests the server for web client.
417	$(GO) run $(GOFLAGS) $(PLATFORM_FILES) test web_client_tests_server
418
419test-client: ## Test client app.
420	@echo Running client tests
421
422	cd $(BUILD_WEBAPP_DIR) && $(MAKE) test
423
424test: test-server test-client ## Runs all checks and tests below (except race detection and postgres).
425
426cover: ## Runs the golang coverage tool. You must run the unit tests first.
427	@echo Opening coverage info in browser. If this failed run make test first
428
429	$(GO) tool cover -html=cover.out
430	$(GO) tool cover -html=ecover.out
431
432test-data: run-server ## Add test data to the local instance.
433	@if ! ./scripts/wait-for-system-start.sh; then \
434		make stop; \
435	fi
436
437	@echo ServiceSettings.EnableLocalMode must be set to true.
438
439	bin/mmctl config set TeamSettings.MaxUsersPerTeam 100 --local
440	bin/mmctl sampledata -u 60 --local
441
442	@echo You may need to restart the Mattermost server before using the following
443	@echo ========================================================================
444	@echo Login with a system admin account username=sysadmin password=Sys@dmin-sample1
445	@echo Login with a regular account username=user-1 password=SampleUs@r-1
446	@echo ========================================================================
447
448validate-go-version: ## Validates the installed version of go against Mattermost's minimum requirement.
449	@if [ $(GO_MAJOR_VERSION) -gt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \
450		exit 0 ;\
451	elif [ $(GO_MAJOR_VERSION) -lt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \
452		echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\
453		exit 1; \
454	elif [ $(GO_MINOR_VERSION) -lt $(MINIMUM_SUPPORTED_GO_MINOR_VERSION) ] ; then \
455		echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\
456		exit 1; \
457	fi
458
459build-templates: ## Compile all mjml email templates
460	cd $(TEMPLATES_DIR) && $(MAKE) build
461
462run-server: prepackaged-binaries validate-go-version start-docker ## Starts the server.
463	@echo Running mattermost for development
464
465	mkdir -p $(BUILD_WEBAPP_DIR)/dist/files
466	$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) $(RUN_IN_BACKGROUND)
467
468debug-server: start-docker ## Compile and start server using delve.
469	mkdir -p $(BUILD_WEBAPP_DIR)/dist/files
470	$(DELVE) debug $(PLATFORM_FILES) --build-flags="-ldflags '\
471		-X github.com/mattermost/mattermost-server/v6/model.BuildNumber=$(BUILD_NUMBER)\
472		-X \"github.com/mattermost/mattermost-server/v6/model.BuildDate=$(BUILD_DATE)\"\
473		-X github.com/mattermost/mattermost-server/v6/model.BuildHash=$(BUILD_HASH)\
474		-X github.com/mattermost/mattermost-server/v6/model.BuildHashEnterprise=$(BUILD_HASH_ENTERPRISE)\
475		-X github.com/mattermost/mattermost-server/v6/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)'"
476
477debug-server-headless: start-docker ## Debug server from within an IDE like VSCode or IntelliJ.
478	mkdir -p $(BUILD_WEBAPP_DIR)/dist/files
479	$(DELVE) debug --headless --listen=:2345 --api-version=2 --accept-multiclient $(PLATFORM_FILES) --build-flags="-ldflags '\
480		-X github.com/mattermost/mattermost-server/v6/model.BuildNumber=$(BUILD_NUMBER)\
481		-X \"github.com/mattermost/mattermost-server/v6/model.BuildDate=$(BUILD_DATE)\"\
482		-X github.com/mattermost/mattermost-server/v6/model.BuildHash=$(BUILD_HASH)\
483		-X github.com/mattermost/mattermost-server/v6/model.BuildHashEnterprise=$(BUILD_HASH_ENTERPRISE)\
484		-X github.com/mattermost/mattermost-server/v6/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)'"
485
486run-cli: start-docker ## Runs CLI.
487	@echo Running mattermost for development
488	@echo Example should be like 'make ARGS="-version" run-cli'
489
490	$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) ${ARGS}
491
492run-client: ## Runs the webapp.
493	@echo Running mattermost client for development
494
495	ln -nfs $(BUILD_WEBAPP_DIR)/dist client
496	cd $(BUILD_WEBAPP_DIR) && $(MAKE) run
497
498run-client-fullmap: ## Legacy alias to run-client
499	@echo Running mattermost client for development
500
501	cd $(BUILD_WEBAPP_DIR) && $(MAKE) run
502
503run: check-prereqs run-server run-client ## Runs the server and webapp.
504
505run-fullmap: run-server run-client ## Legacy alias to run
506
507stop-server: ## Stops the server.
508	@echo Stopping mattermost
509
510ifeq ($(BUILDER_GOOS_GOARCH),"windows_amd64")
511	wmic process where "Caption='go.exe' and CommandLine like '%go.exe run%'" call terminate
512	wmic process where "Caption='mattermost.exe' and CommandLine like '%go-build%'" call terminate
513else
514	@for PID in $$(ps -ef | grep "[g]o run" | awk '{ print $$2 }'); do \
515		echo stopping go $$PID; \
516		kill $$PID; \
517	done
518	@for PID in $$(ps -ef | grep "[g]o-build" | awk '{ print $$2 }'); do \
519		echo stopping mattermost $$PID; \
520		kill $$PID; \
521	done
522endif
523
524stop-client: ## Stops the webapp.
525	@echo Stopping mattermost client
526
527	cd $(BUILD_WEBAPP_DIR) && $(MAKE) stop
528
529stop: stop-server stop-client stop-docker ## Stops server, client and the docker compose.
530
531restart: restart-server restart-client ## Restarts the server and webapp.
532
533restart-server: | stop-server run-server ## Restarts the mattermost server to pick up development change.
534
535restart-haserver:
536	@echo Restarting mattermost in an HA topology
537
538	docker-compose restart follower2
539	docker-compose restart follower
540	docker-compose restart leader
541	docker-compose restart haproxy
542
543restart-client: | stop-client run-client ## Restarts the webapp.
544
545run-job-server: ## Runs the background job server.
546	@echo Running job server for development
547	$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) jobserver &
548
549config-ldap: ## Configures LDAP.
550	@echo Setting up configuration for local LDAP
551
552	@sed -i'' -e 's|"LdapServer": ".*"|"LdapServer": "localhost"|g' config/config.json
553	@sed -i'' -e 's|"BaseDN": ".*"|"BaseDN": "dc=mm,dc=test,dc=com"|g' config/config.json
554	@sed -i'' -e 's|"BindUsername": ".*"|"BindUsername": "cn=admin,dc=mm,dc=test,dc=com"|g' config/config.json
555	@sed -i'' -e 's|"BindPassword": ".*"|"BindPassword": "mostest"|g' config/config.json
556	@sed -i'' -e 's|"FirstNameAttribute": ".*"|"FirstNameAttribute": "cn"|g' config/config.json
557	@sed -i'' -e 's|"LastNameAttribute": ".*"|"LastNameAttribute": "sn"|g' config/config.json
558	@sed -i'' -e 's|"NicknameAttribute": ".*"|"NicknameAttribute": "cn"|g' config/config.json
559	@sed -i'' -e 's|"EmailAttribute": ".*"|"EmailAttribute": "mail"|g' config/config.json
560	@sed -i'' -e 's|"UsernameAttribute": ".*"|"UsernameAttribute": "uid"|g' config/config.json
561	@sed -i'' -e 's|"IdAttribute": ".*"|"IdAttribute": "uid"|g' config/config.json
562	@sed -i'' -e 's|"LoginIdAttribute": ".*"|"LoginIdAttribute": "uid"|g' config/config.json
563	@sed -i'' -e 's|"GroupDisplayNameAttribute": ".*"|"GroupDisplayNameAttribute": "cn"|g' config/config.json
564	@sed -i'' -e 's|"GroupIdAttribute": ".*"|"GroupIdAttribute": "entryUUID"|g' config/config.json
565
566config-reset: ## Resets the config/config.json file to the default.
567	@echo Resetting configuration to default
568	rm -f config/config.json
569	OUTPUT_CONFIG=$(PWD)/config/config.json $(GO) $(GOFLAGS) run ./scripts/config_generator
570
571diff-config: ## Compares default configuration between two mattermost versions
572	@./scripts/diff-config.sh
573
574clean: stop-docker ## Clean up everything except persistant server data.
575	@echo Cleaning
576
577	rm -Rf $(DIST_ROOT)
578	$(GO) clean $(GOFLAGS) -i ./...
579
580	cd $(BUILD_WEBAPP_DIR) && $(MAKE) clean
581
582	find . -type d -name data -not -path './vendor/*' | xargs rm -rf
583	rm -rf logs
584
585	rm -f mattermost.log
586	rm -f mattermost.log.jsonl
587	rm -f npm-debug.log
588	rm -f .prepare-go
589	rm -f enterprise
590	rm -f cover.out
591	rm -f ecover.out
592	rm -f *.out
593	rm -f *.test
594	rm -f imports/imports.go
595	rm -f cmd/mattermost/cprofile*.out
596
597nuke: clean clean-docker ## Clean plus removes persistent server data.
598	@echo BOOM
599
600	rm -rf data
601
602setup-mac: ## Adds macOS hosts entries for Docker.
603	echo $$(boot2docker ip 2> /dev/null) dockerhost | sudo tee -a /etc/hosts
604
605update-dependencies: ## Uses go get -u to update all the dependencies while holding back any that require it.
606	@echo Updating Dependencies
607
608	# Update all dependencies (does not update across major versions)
609	$(GO) get -u ./...
610
611	# Tidy up
612	$(GO) mod tidy
613
614	# Copy everything to vendor directory
615	$(GO) mod vendor
616
617	# Tidy up
618	$(GO) mod tidy
619
620vet: ## Run mattermost go vet specific checks
621	@if ! [ -x "$$(command -v $(GOBIN)/mattermost-govet)" ]; then \
622		echo "mattermost-govet is not installed. Please install it executing \"GO111MODULE=off GOBIN=$(PWD)/bin go get -u github.com/mattermost/mattermost-govet\""; \
623		exit 1; \
624	fi;
625	@VET_CMD="-license -structuredLogging -inconsistentReceiverName -inconsistentReceiverName.ignore=session_serial_gen.go,team_member_serial_gen.go,user_serial_gen.go -emptyStrCmp -tFatal -configtelemetry -errorAssertions"; \
626	if ! [ -z "${MM_VET_OPENSPEC_PATH}" ] && [ -f "${MM_VET_OPENSPEC_PATH}" ]; then \
627		VET_CMD="$$VET_CMD -openApiSync -openApiSync.spec=$$MM_VET_OPENSPEC_PATH"; \
628	else \
629		echo "MM_VET_OPENSPEC_PATH not set or spec yaml path in it is incorrect. Skipping API check"; \
630	fi; \
631	$(GO) vet -vettool=$(GOBIN)/mattermost-govet $$VET_CMD ./...
632ifeq ($(BUILD_ENTERPRISE_READY),true)
633ifneq ($(MM_NO_ENTERPRISE_LINT),true)
634	$(GO) vet -vettool=$(GOBIN)/mattermost-govet -enterpriseLicense -structuredLogging -tFatal ./enterprise/...
635endif
636endif
637
638gen-serialized: ## Generates serialization methods for hot structs
639	# This tool only works at a file level, not at a package level.
640	# There will be some warnings about "unresolved identifiers",
641	# but that is because of the above problem. Since we are generating
642	# methods for all the relevant files at a package level, all
643	# identifiers will be resolved. An alternative to remove the warnings
644	# would be to temporarily move all the structs to the same file,
645	# but that involves a lot of manual work.
646	$(GO) get -modfile=go.tools.mod github.com/tinylib/msgp
647	$(GOBIN)/msgp -file=./model/session.go -tests=false -o=./model/session_serial_gen.go
648	$(GOBIN)/msgp -file=./model/user.go -tests=false -o=./model/user_serial_gen.go
649	$(GOBIN)/msgp -file=./model/team_member.go -tests=false -o=./model/team_member_serial_gen.go
650
651todo: ## Display TODO and FIXME items in the source code.
652	@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime TODO
653	@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime XXX
654	@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime FIXME
655	@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime "FIX ME"
656ifeq ($(BUILD_ENTERPRISE_READY),true)
657	@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime TODO enterprise/
658	@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime XXX enterprise/
659	@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime FIXME enterprise/
660	@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime "FIX ME" enterprise/
661endif
662
663## Help documentatin à la https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
664help:
665	@grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' ./Makefile | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
666	@echo
667	@echo You can modify the default settings for this Makefile creating a file config.mk based on the default-config.mk
668	@echo
669