CHANGES: update v4.0.2 release notes draft
[git-cola.git] / Makefile
blob0c36c1fc5fba8bbd43815661b0ec6fddba913cd6
1 # The default target of this Makefile is...
2 .PHONY: all
3 all::
5 # Development
6 # -----------
7 # make V=1 # V=1 increases verbosity
8 # make develop # pip install --editable .
9 # make test [flags=...] # run tests; flags=-x fails fast, --ff failed first
10 # make test V=2 # run tests; V=2 increases test verbosity
11 # make doc # build docs
12 # make flake8 # python style checks
13 # make pylint [color=1] # run pylint; color=1 colorizes output
14 # make pylint3k [color=1] # run python2+3 compatibility checks
15 # make format # run the black python formatter
16 # make check [color=1] # run test, doc, flake8, pylint3k, and pylint
17 # make check file=<filename> # run checks on <filename>
19 # Release Prep
20 # ------------
21 # make pot # update main translation template
22 # make po # merge translations
23 # make i18n # make pot + make po
25 # Installation
26 # ------------
27 # make prefix=<path> install
28 # DESTDIR is also supported.
30 # The external commands used by this Makefile are...
31 BLACK = black
32 CP = cp
33 FIND = find
34 FLAKE8 = flake8
35 GREP = grep
36 GIT = git
37 MARKDOWN = markdown
38 MSGMERGE = msgmerge
39 MKDIR_P = mkdir -p
40 PIP = pip
41 PYTHON ?= python
42 PYTHON3 ?= python3
43 PYLINT = $(PYTHON) -B -m pylint
44 PYTEST = $(PYTHON) -B -m pytest
45 RM = rm -f
46 RM_R = rm -fr
47 RMDIR = rmdir
48 TAR = tar
49 TOX = tox
50 XARGS = xargs
51 XGETTEXT = xgettext
53 # Flags
54 # -----
55 ifdef V
56 VERBOSE = --verbose
57 ifeq ($(V),2)
58 TEST_VERBOSE = --verbose
59 VERBOSE_SHORT = -vv
60 else
61 VERBOSE_SHORT = -v
62 endif
63 else
64 QUIET = --quiet
65 endif
67 FLAKE8_FLAGS = $(VERBOSE)
69 PYTEST_FLAGS = $(QUIET) $(TEST_VERBOSE)
70 uname_S := $(shell uname -s)
71 ifneq ($(uname_S),Linux)
72 PYTEST_FLAGS += --ignore=cola/inotify.py
73 endif
75 TOX_FLAGS = $(VERBOSE_SHORT) --develop --skip-missing-interpreters
76 TOX_ENVS ?= py{27,36,37,38,39,lint}
78 PYLINT_SCORE_FLAG := $(shell $(PYLINT) --score=no --help >/dev/null 2>&1 && echo " --score=no" || true)
79 PYLINT_FLAGS = --rcfile=.pylintrc
80 ifdef color
81 PYLINT_FLAGS += --output-format=colorized
82 endif
83 ifneq ($(PYLINT_SCORE_FLAGSCORE),)
84 PYLINT_FLAGS += $(PYLINT_SCORE_FLAG)
85 endif
87 # These values can be overridden on the command-line or via config.mak
88 prefix = $(HOME)
89 python_version := $(shell $(PYTHON) -c 'import sys; print("%s.%s" % sys.version_info[:2])')
90 python_lib = python$(python_version)/site-packages
91 pythondir = $(prefix)/lib/$(python_lib)
92 # DESTDIR =
94 cola_base := git-cola
95 cola_app_base= $(cola_base).app
96 cola_app = $(CURDIR)/$(cola_app_base)
97 cola_app_resources = $(cola_app)/Contents/Resources
99 # Read $(VERSION) from cola/_version.py and strip quotes.
100 include cola/_version.py
101 cola_version := $(subst ',,$(VERSION))
102 cola_dist := $(cola_base)-$(cola_version)
104 install_args =
105 ifdef DESTDIR
106 install_args += --root="$(DESTDIR)"
107 export DESTDIR
108 endif
109 install_args += --prefix="$(prefix)"
110 export prefix
112 PYTHON_DIRS = cola
113 PYTHON_DIRS += test
115 ALL_PYTHON_DIRS = $(PYTHON_DIRS)
117 # User customizations
118 -include config.mak
120 all::
122 .PHONY: install
123 install:: all
124 $(PIP) $(QUIET) $(VERBOSE) install $(install_args) .
126 .PHONY: doc
127 doc::
128 $(MAKE) -C docs all
130 .PHONY: html
131 html::
132 $(MAKE) -C docs html
134 .PHONY: man
135 man::
136 $(MAKE) -C docs man
138 .PHONY: install-doc
139 install-doc::
140 $(MAKE) -C docs install
142 .PHONY: install-html
143 install-html::
144 $(MAKE) -C docs install-html
146 .PHONY: install-man
147 install-man::
148 $(MAKE) -C docs install-man
150 .PHONY: uninstall
151 uninstall::
152 $(RM) "$(DESTDIR)$(prefix)"/bin/cola
153 $(RM) "$(DESTDIR)$(prefix)"/bin/git-cola
154 $(RM) "$(DESTDIR)$(prefix)"/bin/git-cola-sequence-editor
155 $(RM) "$(DESTDIR)$(prefix)"/bin/git-dag
156 $(RM) "$(DESTDIR)$(prefix)"/share/applications/git-cola.desktop
157 $(RM) "$(DESTDIR)$(prefix)"/share/applications/git-cola-folder-handler.desktop
158 $(RM) "$(DESTDIR)$(prefix)"/share/applications/git-dag.desktop
159 $(RM) "$(DESTDIR)$(prefix)"/share/metainfo/git-dag.appdata.xml
160 $(RM) "$(DESTDIR)$(prefix)"/share/metainfo/git-cola.appdata.xml
161 $(RM) "$(DESTDIR)$(prefix)"/share/icons/hicolor/scalable/apps/git-cola.svg
162 $(RM_R) "$(DESTDIR)$(prefix)"/share/doc/git-cola
163 $(RM_R) "$(DESTDIR)$(pythondir)"/git_cola-*
164 $(RM_R) "$(DESTDIR)$(pythondir)"/cola
165 $(RMDIR) -p "$(DESTDIR)$(pythondir)" 2>/dev/null || true
166 $(RMDIR) "$(DESTDIR)$(prefix)"/share/applications 2>/dev/null || true
167 $(RMDIR) "$(DESTDIR)$(prefix)"/share/metainfo 2>/dev/null || true
168 $(RMDIR) "$(DESTDIR)$(prefix)"/share/doc 2>/dev/null || true
169 $(RMDIR) "$(DESTDIR)$(prefix)"/share/locale/*/LC_MESSAGES 2>/dev/null || true
170 $(RMDIR) "$(DESTDIR)$(prefix)"/share/locale/* 2>/dev/null || true
171 $(RMDIR) "$(DESTDIR)$(prefix)"/share/locale 2>/dev/null || true
172 $(RMDIR) "$(DESTDIR)$(prefix)"/share/icons/hicolor/scalable/apps 2>/dev/null || true
173 $(RMDIR) "$(DESTDIR)$(prefix)"/share/icons/hicolor/scalable 2>/dev/null || true
174 $(RMDIR) "$(DESTDIR)$(prefix)"/share/icons/hicolor 2>/dev/null || true
175 $(RMDIR) "$(DESTDIR)$(prefix)"/share/icons 2>/dev/null || true
176 $(RMDIR) "$(DESTDIR)$(prefix)"/share 2>/dev/null || true
177 $(RMDIR) "$(DESTDIR)$(prefix)"/bin 2>/dev/null || true
178 $(RMDIR) "$(DESTDIR)$(prefix)" 2>/dev/null || true
180 .PHONY: test
181 test::
182 $(PYTEST) $(PYTEST_FLAGS) $(flags) $(PYTHON_DIRS)
184 .PHONY: coverage
185 coverage::
186 $(PYTEST) $(PYTEST_FLAGS) --cov=cola $(flags) $(PYTHON_DIRS)
188 .PHONY: clean
189 clean::
190 $(FIND) $(ALL_PYTHON_DIRS) -name '*.py[cod]' -print0 | $(XARGS) -0 $(RM)
191 $(FIND) $(ALL_PYTHON_DIRS) -name __pycache__ -print0 | $(XARGS) -0 $(RM_R)
192 $(RM_R) build dist tags git-cola.app
193 $(MAKE) -C docs clean
195 # Update i18n files
196 .PHONY: i18n
197 i18n:: pot
198 i18n:: po
200 # Regenerate git-cola.pot with new translations
201 .PHONY: pot
202 pot::
203 $(XGETTEXT) \
204 --language=Python \
205 --keyword=N_ \
206 --no-wrap \
207 --no-location \
208 --omit-header \
209 --sort-output \
210 --output-dir cola/i18n \
211 --output git-cola.pot \
212 cola/*.py \
213 cola/*/*.py
215 # Update .po files with new translations from git-cola.pot
216 .PHONY: po
217 po::
218 for po in cola/i18n/*.po; \
219 do \
220 $(MSGMERGE) \
221 --no-location \
222 --no-wrap \
223 --no-fuzzy-matching \
224 --sort-output \
225 --output-file $$po.new \
226 $$po \
227 cola/i18n/git-cola.pot \
228 && \
229 mv $$po.new $$po; \
231 done
233 # Build a git-cola.app bundle.
234 .PHONY: git-cola.app
235 git-cola.app::
236 $(MKDIR_P) $(cola_app)/Contents/MacOS
237 $(MKDIR_P) $(cola_app_resources)
238 $(PYTHON3) -m venv $(cola_app_resources)
239 $(cola_app_resources)/bin/pip install --requirement requirements/requirements.txt
240 $(cola_app_resources)/bin/pip install --requirement requirements/requirements-optional.txt
241 $(cola_app_resources)/bin/pip install --requirement requirements/requirements-dev.txt
243 $(CP) contrib/darwin/Info.plist contrib/darwin/PkgInfo $(cola_app)/Contents
244 $(CP) contrib/darwin/git-cola $(cola_app)/Contents/MacOS
245 $(CP) contrib/darwin/git-cola.icns $(cola_app)/Contents/Resources
246 $(MAKE) PIP=$(cola_app_resources)/bin/pip \
247 prefix=$(cola_app_resources) install
248 $(MAKE) SPHINXBUILD=$(cola_app_resources)/bin/sphinx-build \
249 prefix=$(cola_app_resources) install-doc
251 .PHONY: app-tarball
252 app-tarball:: git-cola.app
253 $(TAR) czf $(cola_dist).app.tar.gz $(cola_app_base)
255 # Preview the markdown using "make README.html"
256 %.html: %.md
257 $(MARKDOWN) $< >$@
259 .PHONY: flake8
260 flake8::
261 $(FLAKE8) --version
262 $(FLAKE8) $(FLAKE8_FLAGS) $(flags) \
263 $(ALL_PYTHON_DIRS) contrib
265 .PHONY: pylint3k
266 pylint3k::
267 $(PYLINT) --version
268 $(PYLINT) $(PYLINT_FLAGS) --py3k $(flags) \
269 $(ALL_PYTHON_DIRS)
271 .PHONY: pylint
272 pylint::
273 $(PYLINT) --version
274 $(PYLINT) $(PYLINT_FLAGS) $(flags) \
275 $(ALL_PYTHON_DIRS)
277 # Pre-commit checks
278 .PHONY: check
279 ifdef file
280 check::
281 $(FLAKE8) $(FLAKE8_FLAGS) $(flags) $(file)
282 $(PYLINT) $(PYLINT_FLAGS) --output-format=colorized $(flags) $(file)
283 $(PYLINT) $(PYLINT_FLAGS) --output-format=colorized --py3k $(flags) $(file)
284 else
285 # NOTE: flake8 is not part of "make check" because the pytest-flake8 plugin runs flake8
286 # checks during "make test" via pytest.
287 check:: all
288 check:: test
289 check:: doc
290 check:: pylint3k
291 check:: pylint
292 endif
294 .PHONY: format
295 format::
296 $(GIT) ls-files -- '*.py' | \
297 $(GREP) -v ^qtpy | \
298 $(XARGS) $(BLACK) --skip-string-normalization
300 # Run "make develop" from inside a newly created virtualenv to create an
301 # editable installation.
302 .PHONY: develop
303 develop::
304 $(PIP) install --editable .
306 .PHONY: requirements
307 requirements::
308 $(PIP) install --requirement requirements/requirements.txt
310 .PHONY: requirements-dev
311 requirements-dev::
312 $(PIP) install --requirement requirements/requirements-dev.txt
314 .PHONY: requirements-optional
315 requirements-optional::
316 $(PIP) install --requirement requirements/requirements-optional.txt
318 .PHONY: tox
319 tox::
320 $(TOX) $(TOX_FLAGS) $(flags)
322 .PHONY: tox-check
323 tox-check::
324 $(TOX) $(TOX_FLAGS) --parallel auto -e "$(TOX_ENVS)" $(flags)