blob: 265cdf3393c1d72e956ad1b359ce16e3c14fb416 [file] [log] [blame]
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
# ***************************************************
# WARNING! If you edit this file, also edit Makefile!
# ***************************************************
include version.mk
SHELL=cmd.exe
REBAR=bin\rebar.cmd
MAKE=make -f Makefile.win
# REBAR?=$(shell where rebar.cmd)
# Handle the following scenarios:
# 1. When building from a tarball, use version.mk.
# 2. When building from a clean release tag (#.#.#), use that tag.
# 3. When building from a clean RC tag (#.#.#-RC#), use JUST the version
# number inside the tarball, but use the full name for the name of the
# tarball itself.
# 4. When not on a clean tag, use version.mk + git sha + dirty status.
COUCHDB_GIT_SHA=$(git_sha)
IN_RELEASE = $(shell if not exist .git echo true)
ifeq ($(IN_RELEASE), true)
# 1. Building from tarball, use version.mk.
COUCHDB_VERSION = $(vsn_major).$(vsn_minor).$(vsn_patch)
else
# Gather some additional information.
# We do it this way so we don't bake shell-isms into Makefile
# to make it easier to port to Windows. I know, I know. -jst
# IN_RC contains the -RCx suffix in the name if present
IN_RC = $(shell git describe --tags --always --first-parent \
| grep -Eo -- '-RC[0-9]+' 2>nul)
# ON_TAG matches *ONLY* if we are on a release or RC tag
ON_TAG = $(shell git describe --tags --always --first-parent \
| grep -Eo -- '^[0-9]+\.[0-9]\.[0-9]+(-RC[0-9]+)?$$' 2>nul)
# REL_TAG contains the #.#.# from git describe, which might be used
REL_TAG = $(shell git describe --tags --always --first-parent \
| grep -Eo -- '^[0-9]+\.[0-9]\.[0-9]+' 2>nul)
# DIRTY identifies if we're not on a commit
DIRTY = $(shell git describe --dirty | grep -Eo -- '-dirty' 2>nul)
# COUCHDB_GIT_SHA is our current git hash.
COUCHDB_GIT_SHA=$(shell git rev-parse --short=7 --verify HEAD)
ifeq ($(ON_TAG),)
# 4. Not on a tag.
COUCHDB_VERSION_SUFFIX = $(COUCHDB_GIT_SHA)$(DIRTY)
COUCHDB_VERSION = $(vsn_major).$(vsn_minor).$(vsn_patch)-$(COUCHDB_VERSION_SUFFIX)
else
# 2 and 3. On a tag.
COUCHDB_VERSION = $(REL_TAG)$(DIRTY)
endif
endif
# needed to do text substitutions
comma:= ,
empty:=
space:= $(empty) $(empty)
DESTDIR=
# Rebar options
apps=
skip_deps=folsom,meck,mochiweb,triq,proper,snappy,bcrypt,hyper
suites=
tests=
# no sed on Windows, hard code since apps\suites\tests are empty
EUNIT_OPTS=skip_deps=$(skip_deps)
DIALYZE_OPTS=skip_deps=$(skip_deps)
EXUNIT_OPTS=$(subst $(comma),$(space),$(tests))
#ignore javascript tests
ignore_js_suites=
TEST_OPTS=-c startup_jitter=0 -c default_security=admin_local
################################################################################
# Main commands
################################################################################
.PHONY: all
# target: all - Build everything
all: couch fauxton docs
################################################################################
# Building
################################################################################
.PHONY: couch
# target: couch - Build CouchDB core, use ERL_OPTS to provide custom compiler's options
couch: config.erl
@set COUCHDB_VERSION=$(COUCHDB_VERSION) && set COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) && $(REBAR) compile $(COMPILE_OPTS)
@copy src\couch\priv\couchjs.exe bin
.PHONY: docs
# target: docs - Build documentation
ifeq ($(IN_RELEASE), true)
docs: share\docs\html
else
docs: src\docs\build
endif
.PHONY: fauxton
# target: fauxton - Build Fauxton web UI
fauxton: share\www
################################################################################
# Testing
################################################################################
.PHONY: check
# target: check - Test everything
check: all python-black
@$(MAKE) emilio
@$(MAKE) eunit
@$(MAKE) javascript
@$(MAKE) mango-test
@$(MAKE) elixir
ifdef apps
subdirs = $(apps)
else
subdirs=$(shell dir /b src)
endif
.PHONY: eunit
# target: eunit - Run EUnit tests, use EUNIT_OPTS to provide custom options
eunit: export BUILDDIR = $(shell echo %cd%)
eunit: export ERL_AFLAGS = $(shell echo "-config rel/files/eunit.config")
eunit: export COUCHDB_QUERY_SERVER_JAVASCRIPT = $(shell echo %cd%)/bin/couchjs $(shell echo %cd%)/share/server/main.js
eunit: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1
eunit: couch
@set COUCHDB_VERSION=$(COUCHDB_VERSION) && set COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) && $(REBAR) setup_eunit 2> nul
@cmd /c "FOR %d IN ($(subdirs)) DO set COUCHDB_VERSION=$(COUCHDB_VERSION) & set COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) & $(REBAR) -r eunit $(EUNIT_OPTS) apps=%d"
.PHONY: exunit
# target: exunit - Run ExUnit tests
exunit: export BUILDDIR = $(shell echo %cd%)
exunit: export MIX_ENV=test
exunit: export ERL_LIBS = $(shell echo %cd%)\src
exunit: export ERL_AFLAGS = -config $(shell echo %cd%)/rel/files/eunit.config
exunit: export COUCHDB_QUERY_SERVER_JAVASCRIPT = $(shell echo %cd%)/bin/couchjs $(shell echo %cd%)/share/server/main.js
exunit: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1
exunit: couch elixir-init setup-eunit elixir-check-formatted elixir-credo
@mix test --cover --trace $(EXUNIT_OPTS)
setup-eunit: export BUILDDIR = $(shell pwd)
setup-eunit: export ERL_AFLAGS = "-config $(shell echo %cd%)/rel/files/eunit.config")
setup-eunit:
@$(REBAR) setup_eunit 2> nul
just-eunit: export BUILDDIR = $(shell pwd)
just-eunit: export ERL_AFLAGS = "-config $(shell echo %cd%)/rel/files/eunit.config")
just-eunit:
@$(REBAR) -r eunit $(EUNIT_OPTS)
emilio:
@bin\emilio -c emilio.config src\ | python.exe bin\warnings_in_scope -s 3
.venv/bin/black:
@python.exe -m venv .venv
@.venv\Scripts\pip3.exe install black || copy /b .venv\Scripts\black.exe +,,
# Python code formatter - only runs if we're on Python 3.6 or greater
python-black: .venv/bin/black
@python.exe -c "import sys; exit(1 if sys.version_info < (3,6) else 0)" || \
echo 'Python formatter not supported on Python < 3.6; check results on a newer platform'
@python.exe -c "import sys; exit(1 if sys.version_info >= (3,6) else 0)" || \
.venv\Scripts\black.exe --check \
--exclude="build/|buck-out/|dist/|_build/|\.git/|\.hg/|\.mypy_cache/|\.nox/|\.tox/|\.venv/|src/rebar/pr2relnotes.py|src/fauxton" \
. dev\run test\javascript\run src\mango src\docs
python-black-update: .venv/bin/black
@python.exe -c "import sys; exit(1 if sys.version_info < (3,6) else 0)" || \
echo 'Python formatter not supported on Python < 3.6; check results on a newer platform'
@python.exe -c "import sys; exit(1 if sys.version_info >= (3,6) else 0)" || \
.venv\Scripts\black.exe \
--exclude="build/|buck-out/|dist/|_build/|\.git/|\.hg/|\.mypy_cache/|\.nox/|\.tox/|\.venv/|src/rebar/pr2relnotes.py|src/fauxton" \
. dev\run test\javascript\run src\mango src\docs
.PHONY: elixir
elixir: export MIX_ENV=integration
elixir: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1
elixir: elixir-init elixir-check-formatted elixir-credo devclean
@dev\run $(TEST_OPTS) -a adm:pass -n 1 --enable-erlang-views --no-eval 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)'
.PHONY: elixir-init
elixir-init: MIX_ENV=test
elixir-init: config.erl
@mix local.rebar --force && mix local.hex --force && mix deps.get
.PHONY: elixir-cluster-without-quorum
elixir-cluster-without-quorum: export MIX_ENV=integration
elixir-cluster-without-quorum: elixir-init elixir-check-formatted elixir-credo devclean
@dev\run -n 3 -q -a adm:pass \
--degrade-cluster 2 \
--no-eval 'mix test --trace --only without_quorum_test $(EXUNIT_OPTS)'
.PHONY: elixir-cluster-with-quorum
elixir-cluster-with-quorum: export MIX_ENV=integration
elixir-cluster-with-quorum: elixir-init elixir-check-formatted elixir-credo devclean
@dev\run -n 3 -q -a adm:pass \
--degrade-cluster 1 \
--no-eval 'mix test --trace --only with_quorum_test $(EXUNIT_OPTS)'
.PHONY: elixir-check-formatted
elixir-check-formatted: elixir-init
@mix format --check-formatted
# Credo is a static code analysis tool for Elixir.
# We use it in our tests
.PHONY: elixir-credo
elixir-credo: elixir-init
@mix credo
.PHONY: javascript
# target: javascript - Run JavaScript test suites or specific ones defined by suites option
javascript: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1
javascript: devclean
-@mkdir share\www\script\test
ifeq ($(IN_RELEASE), true)
@copy test\javascript\tests\lorem*.txt share\www\script\test
else
-@mkdir src\fauxton\dist\release\test
@copy test\javascript\tests\lorem*.txt src\fauxton\dist\release\test
endif
@python dev\run -n 1 -q --with-admin-party-please \
--enable-erlang-views \
$(TEST_OPTS) \
'python test\javascript\run --suites "$(suites)" \
--ignore "$(ignore_js_suites)"'
.PHONY: check-qs
# target: check-qs - Run query server tests (ruby and rspec required!)
check-qs:
@QS_LANG=js rspec test\view_server\query_server_spec.rb
.PHONY: mango-test
mango-test: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1
mango-test: devclean all
@cd src\mango && \
python.exe -m venv .venv && \
.venv\Scripts\pip.exe install -r requirements.txt
@cd src\mango && .venv\Scripts\python.exe ..\..\dev\run -n 1 --admin=testuser:testpass .venv\Scripts\nosetests
################################################################################
# Developing
################################################################################
.PHONY: build-plt
# target: build-plt - Build project-specific PLT
build-plt:
@$(REBAR) -r build-plt $(DIALYZE_OPTS)
.PHONY: check-plt
# target: check-plt - Check the PLT for consistency and rebuild it if it is not up-to-date
check-plt:
@$(REBAR) -r check-plt $(DIALYZE_OPTS)
.PHONY: dialyze
# target: dialyze - Analyze the code for discrepancies
dialyze: .rebar
@$(REBAR) -r dialyze $(DIALYZE_OPTS)
.PHONY: introspect
# target: introspect - Check for commits difference between rebar.config and repository
introspect:
@$(REBAR) -r update-deps
@escript build-aux\introspect
################################################################################
# Distributing
################################################################################
.PHONY: dist
# target: dist - Make release tarball
dist: all derived
@.\build-aux\couchdb-build-release.sh $(COUCHDB_VERSION)
@copy -r share\www apache-couchdb-$(COUCHDB_VERSION)\share
@mkdir apache-couchdb-$(COUCHDB_VERSION)\share\docs\html
@copy -r src\docs\build\html apache-couchdb-$(COUCHDB_VERSION)\share\docs
@mkdir apache-couchdb-$(COUCHDB_VERSION)\share\docs\man
@copy src\docs\build\man\apachecouchdb.1 apache-couchdb-$(COUCHDB_VERSION)\share\docs\man
@tar czf apache-couchdb-$(COUCHDB_VERSION).tar.gz apache-couchdb-$(COUCHDB_VERSION)
@echo 'Done: apache-couchdb-$(COUCHDB_VERSION).tar.gz'
.PHONY: release
# target: release - Create an Erlang release including CouchDB!
-include install.mk
release: all
@echo 'Installing CouchDB into rel\couchdb\ ...'
-@rmdir /s/q rel\couchdb
@$(REBAR) generate
@copy src\couch\priv\couchjs.exe rel\couchdb\bin
ifeq ($(with_fauxton), 1)
-@mkdir rel\couchdb\share
-@xcopy share\www rel\couchdb\share\www /E/I
endif
ifeq ($(with_docs), 1)
-@mkdir rel\couchdb\share\www\docs
-@mkdir rel\couchdb\share\docs
ifeq ($(IN_RELEASE), true)
@xcopy share\docs\html rel\couchdb\share\www\docs /E /I
@copy share\docs\man\apachecouchdb.1 rel\couchdb\share\docs\couchdb.1
else
@xcopy src\docs\build\html rel\couchdb\share\www\docs /E /I
@copy src\docs\build\man\apachecouchdb.1 rel\couchdb\share\docs\couchdb.1
endif
endif
@echo ... done
@echo .
@echo You can now copy the rel\couchdb directory anywhere on your system.
@echo Start CouchDB with .\bin\couchdb.cmd from within that directory.
@echo .
.PHONY: install
# target: install- install CouchDB :)
install: release
@echo .
@echo Notice: There is no 'make install' command for CouchDB 2.x+.
@echo .
@echo To install CouchDB into your system, copy the rel\couchdb
@echo to your desired installation location. For example:
@echo xcopy /E rel\couchdb C:\CouchDB\
@echo .
################################################################################
# Cleaning
################################################################################
.PHONY: clean
# target: clean - Remove build artifacts
clean:
@$(REBAR) -r clean
-@rmdir /s/q .rebar
-@del /f/q bin\couchjs.exe
-@rmdir /s/q src\*\ebin
-@rmdir /s/q src\*\.rebar
-@del /f/q/s src\*.dll
-@del /f/q src\couch\priv\*.exe
-@del /f/q share\server\main.js share\server\main-coffee.js
-@rmdir /s/q tmp
-@rmdir /s/q dev\data
-@rmdir /s/q dev\lib
-@rmdir /s/q dev\logs
-@rmdir /s/q src\mango\.venv
-@del /f/q src\couch\priv\couch_js\config.h
-@del /f/q dev\boot_node.beam dev\pbkdf2.pyc log\crash.log
.PHONY: distclean
# target: distclean - Remove build and release artifacts
distclean: clean
-@del install.mk
-@del config.erl
-@del rel\couchdb.config
ifneq ($(IN_RELEASE), true)
# when we are in a release, don’t delete the
# copied sources, generated docs, or fauxton
-@rmdir /s/q rel\couchdb
-@rmdir /s/q share\www
-@rmdir /s/q src\docs
endif
.PHONY: devclean
# target: devclean - Remove dev cluster artifacts
devclean:
-@rmdir /s/q dev\lib\node1\data
-@rmdir /s/q dev\lib\node2\data
-@rmdir /s/q dev\lib\node3\data
################################################################################
# Misc
################################################################################
.rebar: build-plt
config.erl:
@echo Apache CouchDB has not been configured.
@echo Try "powershell -ExecutionPolicy Bypass .\configure.ps1 -?" for help.
@echo You probably want "powershell -ExecutionPolicy Bypass .\configure.ps1 -WithCurl".
@echo.
@false
src\docs\build:
@echo 'Building docs...'
ifeq ($(with_docs), 1)
@cd src\docs && make.bat html && make.bat man
endif
share\www:
ifeq ($(with_fauxton), 1)
@echo 'Building Fauxton'
@cd src\fauxton && npm install --production && .\node_modules\.bin\grunt couchdb
endif
derived:
@echo "COUCHDB_GIT_SHA: $(COUCHDB_GIT_SHA)"
@echo "COUCHDB_VERSION: $(COUCHDB_VERSION)"
@echo "COUCHDB_VERSION_SUFFIX: $(COUCHDB_VERSION_SUFFIX)"
@echo "DIRTY: $(DIRTY)"
@echo "IN_RC: $(IN_RC)"
@echo "IN_RELEASE: $(IN_RELEASE)"
@echo "ON_TAG: $(ON_TAG)"
@echo "REL_TAG: $(REL_TAG)"
@echo "SUB_VSN: $(SUB_VSN)"