59555d4a54dd9f092f07dd45d89686ad880f8439
[scm/test.git] / Makefile
1 # GIT_LFS_SHA is the '--short'-form SHA1 of the current revision of Git LFS.
2 GIT_LFS_SHA ?= $(shell git rev-parse --short HEAD)
3 # VERSION is the longer-form describe output of the current revision of Git LFS,
4 # used for identifying intermediate releases.
5 #
6 # If Git LFS is being built for a published release, VERSION and GIT_LFS_SHA
7 # should be identical.
8 VERSION ?= $(shell git describe HEAD)
9
10 # GO is the name of the 'go' binary used to compile Git LFS.
11 GO ?= go
12
13 # GO_TEST_EXTRA_ARGS are extra arguments given to invocations of 'go test'.
14 #
15 # Examples include:
16 #
17 #       make test GO_TEST_EXTRA_ARGS=-v
18 #       make test GO_TEST_EXTRA_ARGS='-run TestMyExample'
19 GO_TEST_EXTRA_ARGS =
20
21 # BUILTIN_LD_FLAGS are the internal flags used to pass to the linker. By default
22 # the config.GitCommit variable is always set via this variable, and
23 # DWARF-stripping is enabled unless DWARF=YesPlease.
24 BUILTIN_LD_FLAGS =
25 BUILTIN_LD_FLAGS += -X github.com/git-lfs/git-lfs/config.GitCommit=$(GIT_LFS_SHA)
26 ifneq ("$(DWARF)","YesPlease")
27 BUILTIN_LD_FLAGS += -s
28 BUILTIN_LD_FLAGS += -w
29 endif
30 # EXTRA_LD_FLAGS are given by the caller, and are passed to the Go linker after
31 # BUILTIN_LD_FLAGS are processed.
32 EXTRA_LD_FLAGS =
33 # LD_FLAGS is the union of the above two BUILTIN_LD_FLAGS and EXTRA_LD_FLAGS.
34 LD_FLAGS = $(BUILTIN_LD_FLAGS) $(EXTRA_LD_FLAGS)
35
36 # BUILTIN_GC_FLAGS are the internal flags used to pass compiler.
37 BUILTIN_GC_FLAGS =
38 # EXTRA_GC_FLAGS are the caller-provided flags to pass to the compiler.
39 EXTRA_GC_FLAGS =
40 # GC_FLAGS are the union of the above two BUILTIN_GC_FLAGS and EXTRA_GC_FLAGS.
41 GC_FLAGS = $(BUILTIN_GC_FLAGS) $(EXTRA_GC_FLAGS)
42
43 # GLIDE is the name of the 'glide' binary used to manage vendored dependencies.
44 GLIDE ?= glide
45
46 # RONN is the name of the 'ronn' program used to generate man pages.
47 RONN ?= ronn
48 # RONN_EXTRA_ARGS are extra arguments given to the $(RONN) program when invoked.
49 RONN_EXTRA_ARGS ?=
50
51 # GREP is the name of the program used for regular expression matching, or
52 # 'grep' if unset.
53 GREP ?= grep
54 # RM is the name of the program used removing files, or 'rm -f' if unset.
55 RM ?= rm -f
56 # XARGS is the name of the program used to turn stdin into program arguments, or
57 # 'xargs' if unset.
58 XARGS ?= xargs
59
60 # GOIMPORTS is the name of the program formatter used before compiling.
61 GOIMPORTS ?= goimports
62 # GOIMPORTS_EXTRA_OPTS are the default options given to the $(GOIMPORTS)
63 # program.
64 GOIMPORTS_EXTRA_OPTS ?= -w -l
65
66 # SOURCES is a listing of all .go files in this and child directories, excluding
67 # that in vendor.
68 SOURCES = $(shell find . -type f -name '*.go' | grep -v vendor)
69 # PKGS is a listing of packages that are considered to be a part of Git LFS, and
70 # are used in package-specific commands, such as the 'make test' targets. For
71 # example:
72 #
73 #       make test                               # run 'go test' in all packages
74 #       make PKGS='config git/githistory' test  # run 'go test' in config and
75 #                                               # git/githistory
76 #
77 # By default, it is a listing of all packages in Git LFS. When new packages (or
78 # sub-packages) are created, they should be added here.
79 ifndef PKGS
80 PKGS =
81 PKGS += commands
82 PKGS += config
83 PKGS += errors
84 PKGS += filepathfilter
85 PKGS += fs
86 PKGS += git
87 PKGS += git/gitattr
88 PKGS += git/githistory
89 PKGS += git
90 PKGS += lfs
91 PKGS += lfsapi
92 PKGS += locking
93 PKGS += subprocess
94 PKGS += tasklog
95 PKGS += tools
96 PKGS += tools/humanize
97 PKGS += tools/kv
98 PKGS += tq
99 endif
100
101 # X is the platform-specific extension for Git LFS binaries. It is automatically
102 # set to .exe on Windows, and the empty string on all other platforms. It may be
103 # overridden.
104 #
105 # BUILD_MAIN is the main ".go" file that contains func main() for Git LFS. On
106 # macOS and other non-Windows platforms, it is required that a specific
107 # entrypoint be given, hence the below conditional. On Windows, it is required
108 # that an entrypoint not be given so that goversioninfo can successfully embed
109 # the resource.syso file (for more, see below).
110 ifeq ($(OS),Windows_NT)
111 X ?= .exe
112 BUILD_MAIN ?=
113 else
114 X ?=
115 BUILD_MAIN ?= ./git-lfs.go
116 endif
117
118 # BUILD is a macro used to build a single binary of Git LFS using the above
119 # LD_FLAGS and GC_FLAGS.
120 #
121 # It takes three arguments:
122 #
123 #       $(1) - a valid GOOS value, or empty-string
124 #       $(2) - a valid GOARCH value, or empty-string
125 #       $(3) - an optional program extension. If $(3) is given as '-foo', then the
126 #              program will be written to bin/git-lfs-foo.
127 #
128 # It uses BUILD_MAIN as defined above to specify the entrypoint for building Git
129 # LFS.
130 BUILD = GOOS=$(1) GOARCH=$(2) \
131         $(GO) build \
132         -ldflags="$(LD_FLAGS)" \
133         -gcflags="$(GC_FLAGS)" \
134         -o ./bin/git-lfs$(3) $(BUILD_MAIN)
135
136 # BUILD_TARGETS is the set of all platforms and architectures that Git LFS is
137 # built for.
138 BUILD_TARGETS = bin/git-lfs-darwin-amd64 bin/git-lfs-darwin-386 \
139         bin/git-lfs-linux-amd64 bin/git-lfs-linux-386 \
140         bin/git-lfs-freebsd-amd64 bin/git-lfs-freebsd-386 \
141         bin/git-lfs-windows-amd64.exe bin/git-lfs-windows-386.exe
142
143 # Targets 'all' and 'build' build binaries of Git LFS for the above release
144 # matrix.
145 .PHONY : all build
146 all build : $(BUILD_TARGETS)
147
148 # The following bin/git-lfs-% targets make a single binary compilation of Git
149 # LFS for a specific operating system and architecture pair.
150 #
151 # They function by translating target names into arguments for the above BUILD
152 # builtin, and appending the appropriate suffix to the build target.
153 #
154 # On Windows, they also depend on the resource.syso target, which installs and
155 # embeds the versioninfo into the binary.
156 bin/git-lfs-darwin-amd64 : $(SOURCES)
157         $(call BUILD,darwin,amd64,-darwin-amd64)
158 bin/git-lfs-darwin-386 : $(SOURCES)
159         $(call BUILD,darwin,386,-darwin-386)
160 bin/git-lfs-linux-amd64 : $(SOURCES)
161         $(call BUILD,linux,amd64,-linux-amd64)
162 bin/git-lfs-linux-386 : $(SOURCES)
163         $(call BUILD,linux,386,-linux-386)
164 bin/git-lfs-freebsd-amd64 : $(SOURCES)
165         $(call BUILD,freebsd,amd64,-freebsd-amd64)
166 bin/git-lfs-freebsd-386 : $(SOURCES)
167         $(call BUILD,freebsd,386,-freebsd-386)
168 bin/git-lfs-windows-amd64.exe : resource.syso $(SOURCES)
169         $(call BUILD,windows,amd64,-windows-amd64.exe)
170 bin/git-lfs-windows-386.exe : resource.syso $(SOURCES)
171         $(call BUILD,windows,386,-windows-386.exe)
172
173 # .DEFAULT_GOAL sets the operating system-appropriate Git LFS binary as the
174 # default output of 'make'.
175 .DEFAULT_GOAL := bin/git-lfs$(X)
176
177 # bin/git-lfs targets the default output of Git LFS on non-Windows operating
178 # systems, and respects the build knobs as above.
179 bin/git-lfs : $(SOURCES) fmt
180         $(call BUILD,$(GOOS),$(GOARCH),)
181
182 # bin/git-lfs.exe targets the default output of Git LFS on Windows systems, and
183 # respects the build knobs as above.
184 bin/git-lfs.exe : $(SOURCES) resource.syso
185         $(call BUILD,$(GOOS),$(GOARCH),.exe)
186
187 # resource.syso installs the 'goversioninfo' command and uses it in order to
188 # generate a binary that has information included necessary to create the
189 # Windows installer.
190 resource.syso:
191         @$(GO) get github.com/josephspurrier/goversioninfo/cmd/goversioninfo
192         $(GO) generate
193
194 # RELEASE_TARGETS is the set of all release artifacts that we generate over a
195 # particular release. They each have a corresponding entry in BUILD_TARGETS as
196 # above.
197 #
198 # Unlike BUILD_TARGETS above, each of the below create a compressed directory
199 # containing the matching binary, as well as the contents of RELEASE_INCLUDES
200 # below.
201 #
202 # To build a specific release, execute the following:
203 #
204 #       make bin/releases/git-lfs-darwin-amd64-$(git describe HEAD).tar.gz
205 #
206 # To build a specific release with a custom VERSION suffix, run the following:
207 #
208 #       make VERSION=my-version bin/releases/git-lfs-darwin-amd64-my-version.tar.gz
209 RELEASE_TARGETS = bin/releases/git-lfs-darwin-amd64-$(VERSION).tar.gz \
210         bin/releases/git-lfs-darwin-386-$(VERSION).tar.gz \
211         bin/releases/git-lfs-linux-amd64-$(VERSION).tar.gz \
212         bin/releases/git-lfs-linux-386-$(VERSION).tar.gz \
213         bin/releases/git-lfs-freebsd-amd64-$(VERSION).tar.gz \
214         bin/releases/git-lfs-freebsd-386-$(VERSION).tar.gz \
215         bin/releases/git-lfs-windows-amd64-$(VERSION).zip \
216         bin/releases/git-lfs-windows-386-$(VERSION).zip
217
218 # RELEASE_INCLUDES are the names of additional files that are added to each
219 # release artifact.
220 RELEASE_INCLUDES = README.md CHANGELOG.md
221
222 # release is a phony target that builds all of the release artifacts, and then
223 # shows the SHA 256 signature of each.
224 #
225 # To build all of the release binaries for a given Git LFS release:
226 #
227 #       make release
228 .PHONY : release
229 release : $(RELEASE_TARGETS)
230         shasum -a 256 $(RELEASE_TARGETS)
231
232 # bin/releases/git-lfs-%-$(VERSION).tar.gz generates a gzip-compressed TAR of
233 # the non-Windows release artifacts.
234 #
235 # It includes all of RELEASE_INCLUDES, as well as script/install.sh.
236 bin/releases/git-lfs-%-$(VERSION).tar.gz : \
237 $(RELEASE_INCLUDES) bin/git-lfs-% script/install.sh
238         @mkdir -p bin/releases
239         tar -s '!bin/git-lfs-.*!git-lfs!' -s '!script/!!' -czf $@ $^
240
241 # bin/releases/git-lfs-%-$(VERSION).zip generates a ZIP compression of all of
242 # the Windows release artifacts.
243 #
244 # It includes all of the RELEASE_INCLUDES, and converts LF-style line endings to
245 # CRLF in the non-binary components of the artifact.
246 bin/releases/git-lfs-%-$(VERSION).zip : $(RELEASE_INCLUDES) bin/git-lfs-%.exe
247         @mkdir -p bin/releases
248         zip -j -l $@ $^
249
250 # TEST_TARGETS is a list of all phony test targets. Each one of them corresponds
251 # to a specific kind or subset of tests to run.
252 TEST_TARGETS := test-bench test-verbose test-race
253 .PHONY : $(TEST_TARGETS) test
254 $(TEST_TARGETS) : test
255
256 # test-bench runs all Go benchmark tests, and nothing more.
257 test-bench : GO_TEST_EXTRA_ARGS=-run=__nothing__ -bench=.
258 # test-verbose runs all Go tests in verbose mode.
259 test-verbose : GO_TEST_EXTRA_ARGS=-v
260 # test-race runs all Go tests in race-detection mode.
261 test-race : GO_TEST_EXTRA_ARGS=-race
262
263 # test runs the Go tests with GO_TEST_EXTRA_ARGS in all specified packages,
264 # given by the PKGS variable.
265 #
266 # For example, a caller can invoke the race-detection tests in just the config
267 # package by running:
268 #
269 #               make PKGS=config test-race
270 #
271 # Or in a series of packages, like:
272 #
273 #               make PKGS="config lfsapi tools/kv" test-race
274 #
275 # And so on.
276 test : fmt
277         $(GO) test $(GO_TEST_EXTRA_ARGS) $(addprefix ./,$(PKGS))
278
279 # integration is a shorthand for running 'make' in the 't' directory.
280 .PHONY : integration
281 integration : bin/git-lfs$(X)
282         make -C t test
283
284 # glide.lock is the permanent record of the glide.yaml file, and it is built by
285 # running 'glide update'.
286 glide.lock : glide.yaml
287         $(GLIDE) update
288
289 # vendor updates the glide.lock-file, and installs vendored dependencies into
290 # the vendor/ sub-tree, removing sub-packages (listed below) that are unused by
291 # Git LFS.
292 .PHONY : vendor
293 vendor : glide.lock
294         $(GLIDE) install
295         $(RM) -r vendor/github.com/ThomsonReutersEikon/go-ntlm/utils
296         $(RM) -r vendor/github.com/davecgh/go-spew
297         $(RM) -r vendor/github.com/pmezard/go-difflib
298
299 # fmt runs goimports over all files in Git LFS (as defined by $(SOURCES) above),
300 # and replaces their contents with a formatted one in-place.
301 #
302 # If $(GOIMPORTS) does not exist, or isn't otherwise executable, this recipe
303 # still performs the linting sequence, but gracefully skips over running a
304 # non-existent command.
305 .PHONY : fmt
306 ifeq ($(shell test -x "`which $(GOIMPORTS)`"; echo $$?),0)
307 fmt : $(SOURCES) | lint
308         $(GOIMPORTS) $(GOIMPORTS_EXTRA_OPTS) $?;
309 else
310 fmt : $(SOURCES) | lint
311         @echo "git-lfs: skipping fmt, no goimports found at \`$(GOIMPORTS)\` ..."
312 endif
313
314 # lint ensures that there are all dependencies outside of the standard library
315 # are vendored in via vendor (see: above).
316 .PHONY : lint
317 lint : $(SOURCES)
318         $(GO) list -f '{{ join .Deps "\n" }}' . \
319         | $(XARGS) $(GO) list -f '{{ if not .Standard }}{{ .ImportPath }}{{ end }}' \
320         | $(GREP) -v "github.com/git-lfs/git-lfs" || exit 0
321
322 # MAN_ROFF_TARGETS is a list of all ROFF-style targets in the man pages.
323 MAN_ROFF_TARGETS = man/git-lfs-checkout.1 \
324   man/git-lfs-clean.1 \
325   man/git-lfs-clone.1 \
326   man/git-lfs-config.5 \
327   man/git-lfs-env.1 \
328   man/git-lfs-ext.1 \
329   man/git-lfs-fetch.1 \
330   man/git-lfs-filter-process.1 \
331   man/git-lfs-fsck.1 \
332   man/git-lfs-install.1 \
333   man/git-lfs-lock.1 \
334   man/git-lfs-locks.1 \
335   man/git-lfs-logs.1 \
336   man/git-lfs-ls-files.1 \
337   man/git-lfs-migrate.1 \
338   man/git-lfs-pointer.1 \
339   man/git-lfs-post-checkout.1 \
340   man/git-lfs-post-merge.1 \
341   man/git-lfs-pre-push.1 \
342   man/git-lfs-prune.1 \
343   man/git-lfs-pull.1 \
344   man/git-lfs-push.1 \
345   man/git-lfs-smudge.1 \
346   man/git-lfs-status.1 \
347   man/git-lfs-track.1 \
348   man/git-lfs-uninstall.1 \
349   man/git-lfs-unlock.1 \
350   man/git-lfs-untrack.1 \
351   man/git-lfs-update.1 \
352   man/git-lfs.1
353
354 # MAN_HTML_TARGETS is a list of all HTML-style targets in the man pages.
355 MAN_HTML_TARGETS = man/git-lfs-checkout.1.html \
356   man/git-lfs-clean.1.html \
357   man/git-lfs-clone.1.html \
358   man/git-lfs-config.5.html \
359   man/git-lfs-env.1.html \
360   man/git-lfs-ext.1.html \
361   man/git-lfs-fetch.1.html \
362   man/git-lfs-filter-process.1.html \
363   man/git-lfs-fsck.1.html \
364   man/git-lfs-install.1.html \
365   man/git-lfs-lock.1.html \
366   man/git-lfs-locks.1.html \
367   man/git-lfs-logs.1.html \
368   man/git-lfs-ls-files.1.html \
369   man/git-lfs-migrate.1.html \
370   man/git-lfs-pointer.1.html \
371   man/git-lfs-post-checkout.1.html \
372   man/git-lfs-post-merge.1.html \
373   man/git-lfs-pre-push.1.html \
374   man/git-lfs-prune.1.html \
375   man/git-lfs-pull.1.html \
376   man/git-lfs-push.1.html \
377   man/git-lfs-smudge.1.html \
378   man/git-lfs-status.1.html \
379   man/git-lfs-track.1.html \
380   man/git-lfs-uninstall.1.html \
381   man/git-lfs-unlock.1.html \
382   man/git-lfs-untrack.1.html \
383   man/git-lfs-update.1.html \
384   man/git-lfs.1.html
385
386 # man generates all ROFF- and HTML-style manpage targets.
387 .PHONY : man
388 man : $(MAN_ROFF_TARGETS) $(MAN_HTML_TARGETS)
389
390 # man/% generates ROFF-style man pages from the corresponding .ronn file.
391 man/% : docs/man/%.ronn
392         @mkdir -p man
393         $(RONN) $(RONN_EXTRA_ARGS) -r --pipe < $^ > $@
394
395 # man/%.html generates HTML-style man pages from the corresponding .ronn file.
396 man/%.html : docs/man/%.ronn
397         @mkdir -p man
398         $(RONN) $(RONN_EXTRA_ARGS) -5 --pipe < $^ > $@