You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Makefile 11 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
5 years ago
5 years ago
5 years ago
5 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. # Makefile --- 10sr make dotfiles
  2. # 2014, 10sr. Unlicensed <http://unlicense.org>
  3. # TODO: Add help message
  4. # Variable definitions
  5. dotfiles_url_base := https://raw.githubusercontent.com/10sr/dotfiles/master
  6. use_git ?= t
  7. git_auth ?= t
  8. dotfiles_git_path := 10sr/dotfiles.git
  9. ifneq (,$(git_auth))
  10. $(warning 'git_auth' is not empty. Use git repository with push right.)
  11. dotfiles_git := git@github.com:$(dotfiles_git_path)
  12. else
  13. $(warning 'git_auth' is empty. Use public read-only git repository.)
  14. dotfiles_git := https://github.com/$(dotfiles_git_path)
  15. endif
  16. current_origin_url := $(shell git config remote.origin.url)
  17. ifeq (,$(dotfiles_dir))
  18. ifneq (,$(findstring $(dotfiles_git_path),$(current_origin_url)))
  19. $(warning Currently in dotfiles repository)
  20. dotfiles_dir := $(PWD)
  21. else
  22. # Current directory is not 10sr/dotfiles.git reposioty
  23. ifeq (,$(DOTFILES_DIR))
  24. $(warning Neigher 'DOTFILES_DIR' nor 'dotfiles_dir' is defined)
  25. $(warning Use default value)
  26. dotfiles_dir := $(HOME)/10sr_dotfiles
  27. else
  28. # dotfiles_dir is empty but DOTFILES_DIR has a value
  29. $(warning 'dotfiles_dir' is set from 'DOTFILES_DIR')
  30. dotfiles_dir := $(DOTFILES_DIR)
  31. endif
  32. endif
  33. endif
  34. $(warning dotfiles_dir: $(dotfiles_dir))
  35. dotfiles_home_dir := $(dotfiles_dir)/.home
  36. ifeq ($(home),)
  37. ifeq ($(global_home),)
  38. $(warning 'home' not set and 'global_home' is empty)
  39. # TODO: What this should be?
  40. home := $(dotfiles_home_dir)
  41. else
  42. home := $(HOME)
  43. endif
  44. endif
  45. $(warning home: $(home))
  46. localdir := $(home)/.local
  47. vardir := $(home)/.var
  48. bindir := $(localdir)/bin
  49. directories := $(dotfiles_dir) $(home) $(localdir) $(vardir) $(bindir) \
  50. $(home)/.emacs.d
  51. current := $(shell date)
  52. uname := $(shell uname)
  53. # Remove zsh from this list because it causes failure of travis test
  54. # Message:
  55. # Segmentation fault (core dumped)
  56. shrc_loadables := sh bash # zsh
  57. emacs ?= $(shell which emacs 2>/dev/null)
  58. git ?= $(shell which git 2>/dev/null)
  59. curl ?= $(shell which curl 2>/dev/null)
  60. grep ?= GREP_OPTIONS= $(shell which grep 2>/dev/null)
  61. ifeq ($(emacs),)
  62. $(warning Emacs program not found)
  63. endif
  64. files := Makefile emacs.el profile shrc tmux.conf vimrc _keysnail.js
  65. # Targets
  66. default: help
  67. tests := test-el
  68. test: test-syntax $(tests) ## Execute some tests
  69. test_syntaxes := test-syntax-el test-syntax-sh
  70. test-syntax: $(test_syntaxes) ## Execute syntax check
  71. setups := setup-darwin setup-directories setup-emacs setup-gitconf \
  72. setup-repository setup-rc
  73. # `make setup` to setup these all sounds to be too match
  74. setup-all: $(setups) ## Run initialization tasks
  75. runs := run-emacs run-bash run-zsh
  76. # Alias for test
  77. check: test
  78. # Similarly, check-syntax is test-syntax
  79. check-syntax: test-syntax
  80. .PHONY: all default clean \
  81. test check $(tests) \
  82. test-syntax check-syntax $(test_syntaxes)\
  83. setup-all $(setups)
  84. $(directories):
  85. test -d "$@" || mkdir -vp "$@"
  86. # System detection
  87. # ================
  88. # Is this usefull? Just checking uname is not enough?
  89. ismsys :=
  90. iscygwin :=
  91. iswindows :=
  92. isdarwin :=
  93. isfreebsd :=
  94. isbsd :=
  95. islinux :=
  96. ifneq (,$(findstring MINGW,$(uname)))
  97. ismsys := t
  98. endif
  99. ifneq (,$(findstring CYGWIN,$(uname)))
  100. iscygwin := t
  101. endif
  102. ifneq (,$(ismsys)$(iscygwin))
  103. iswindows := t
  104. endif
  105. ifneq (,$(findstring Darwin,$(uname)))
  106. isdarwin := t
  107. endif
  108. ifneq (,$(findstring FreeBSD,$(uname)))
  109. isfreebsd := t
  110. endif
  111. ifneq (,$(isdarwin)$(isfreebsd))
  112. isbsd := t
  113. endif
  114. ifneq (,$(findstring Linux,$(uname)))
  115. islinux := t
  116. endif
  117. # Help
  118. # ====
  119. help:
  120. @echo "10sr Makefile" | (figlet || cat) | (lolcat || cat)
  121. @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
  122. awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
  123. # Clean
  124. # =====
  125. # Usage: Define a target as a dependency for clean and .PHONY
  126. clean: clean-home
  127. .PHONY: clean-home
  128. clean-home:
  129. $(RM) -r $(dotfiles_home_dir)
  130. # preparing files
  131. # ===============
  132. files_fullpath := $(files:%=$(dotfiles_dir)/%)
  133. fetch_files := $(files:%=fetch-%)
  134. .PHONY: $(fetch_files)
  135. $(fetch_files): fetch-%: $(dotfiles_dir)
  136. curl --url $(dotfiles_url_base)/$* --output $@
  137. ifeq (,$(use_git))
  138. $(files_fullpath): $(dotfiles_dir)/%: fetch-%
  139. $(warning 'use_git' is empty. Use curl to fetch files)
  140. else
  141. $(warning 'use_git' is not empty. Use git to retrieve files)
  142. $(files_fullpath): setup-repository
  143. test -f "$@"
  144. endif
  145. # setups
  146. # ======
  147. # setup git repository
  148. # --------------------
  149. setup-repository: $(dotfiles_dir)/.git
  150. $(dotfiles_dir)/.git:
  151. ifeq (,$(git))
  152. false "Git not installed"
  153. endif
  154. $(git) clone $(dotfiles_git) $(dotfiles_dir)
  155. # darwin setup
  156. # ------------
  157. setup_darwins := setup-darwin-defaults setup-darwin-daemon
  158. setup-darwin: $(setup_darwins)
  159. .PHONY: $(setup_darwins)
  160. setup-darwin-defaults:
  161. # http://appdrill.net/60641/mac-boot-mute.html
  162. #sudo nvram SystemAudioVolume=%80
  163. # add quit entry in menu
  164. defaults write com.apple.finder QuitMenuItem -bool YES
  165. # show full path on titlebar
  166. defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES
  167. # do not show desktop icons
  168. defaults write com.apple.finder CreateDesktop -boolean false
  169. killall Finder
  170. # disable dashboard
  171. #defaults write com.apple.dashboard mcx-disabled -bool YES
  172. setup-darwin-daemon:
  173. test "`launchctl getenv LC_ALL`" = C || sudo launchctl setenv LC_ALL C
  174. if ! (launchctl list | grep com.apple.locate) >/dev/null ;\
  175. then \
  176. sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist ;\
  177. fi
  178. # emacs setup
  179. # -----------
  180. setup-emacs: $(dotfiles_dir)/emacs.el
  181. test -n "$(emacs)" && $(emacs) -q --batch \
  182. --eval "(setq user-emacs-directory \"$(home)/.emacs.d/\")" \
  183. --load $< \
  184. -f my-auto-install-package
  185. # git config setup
  186. # ----------------
  187. ifneq (,$(git))
  188. git_conf := $(git) config --global
  189. endif
  190. xz := $(shell which xz 2>/dev/null)
  191. setup-gitconf: ## Set git configurations
  192. ifeq (,$(git))
  193. $(warnning "Git program not found")
  194. else
  195. $(git_conf) user.name '10sr'
  196. $(git_conf) user.email '8.slashes@gmail.com'
  197. $(git_conf) core.autocrlf false
  198. $(git_conf) core.excludesfile '~/.gitignore'
  199. $(git_conf) core.commentChar ";"
  200. $(git_conf) core.notesRef true
  201. $(git_conf) color.ui auto
  202. $(git_conf) status.relativePaths false
  203. $(git_conf) status.showUntrackedFiles normal
  204. $(git_conf) log.date iso
  205. $(git_conf) fetch.prune true
  206. $(git_conf) fetch.pruneTags true
  207. $(git_conf) push.default current
  208. $(git_conf) pull.ff only
  209. $(git_conf) rebase.stat true
  210. $(git_conf) rebase.missingCommitsCheck error
  211. ifneq (,$(xz))
  212. $(git_conf) tar.txz.command "xz -c"
  213. endif
  214. $(git_conf) tag.forceSignAnnotated true
  215. $(git_conf) tag.sort "version:refname"
  216. $(git_conf) alias.graph "log --graph --date-order -C -M --pretty=tformat:\"%C(green)%h%C(reset) %C(white)%ad%C(reset) %C(red)%an%C(reset)%C(yellow)%d%C(reset) %C(white bold)%s%C(reset)\" --date=short -n 499"
  217. $(git_conf) alias.px "log -p -G" # pickaxe
  218. $(git_conf) alias.st "status -s -b"
  219. $(git_conf) alias.b "branch"
  220. $(git_conf) alias.sb "show-branch"
  221. $(git_conf) alias.ci "commit --verbose --allow-empty"
  222. # TODO: Try rebase --interactive --autosquash
  223. $(git_conf) alias.cf "commit --verbose --fixup=HEAD -m WIP"
  224. $(git_conf) alias.co "! echo alias co is removed, use si and re instead; false"
  225. $(git_conf) alias.si "switch"
  226. $(git_conf) alias.re "restore"
  227. $(git_conf) alias.cim "commit --verbose -m"
  228. $(git_conf) alias.di "diff --color"
  229. $(git_conf) alias.me "merge --no-ff --stat --verbose"
  230. $(git_conf) alias.ffme "merge --ff-only --stat --verbose"
  231. $(git_conf) alias.gr "grep -n"
  232. $(git_conf) alias.atag "tag --annotated"
  233. $(git_conf) alias.stag "tag --sign"
  234. $(git_conf) alias.ls "ls-files"
  235. # $(git_conf) alias.ls "ls-files -v --full-name"
  236. # $(git_conf) alias.ls "status -u -s ."
  237. $(git_conf) alias.sl "!sl"
  238. # $(git_conf) alias.my-ls "ls-files | xargs ls"
  239. # $(git_conf) alias.ll "!git ls-files | xargs ls -l -CFG --color=auto --time-style=long-iso"
  240. $(git_conf) alias.addi "add -i"
  241. # Add patch to index
  242. $(git_conf) alias.ap "apply --cached"
  243. $(git_conf) alias.clean-p "diff --quiet"
  244. $(git_conf) alias.echo-ref "for-each-ref --format='%(refname:short)'"
  245. $(git_conf) alias.todo "grep -nH -E -i 'todo:|note:|fixme:'"
  246. $(git_conf) alias.stashsnap '! gitdir="`git rev-parse --git-dir`" && : >>"$$gitdir"/logs/refs/snapshot && cmt=`git stash create` && test -n "$$cmt" && git update-ref refs/snapshot $$cmt && echo Snapshot created: $$cmt'
  247. #$(git_conf) alias.snap '! gitdir="`git rev-parse --git-dir`" && export GIT_INDEX_FILE="$$gitdir"/snapshot.index && cp -pf "$$gitdir"/index "$$GIT_INDEX_FILE" && git add -Av && : >>"$$gitdir"/logs/refs/snapshot && git update-ref refs/snapshot $$(git commit-tree $$(git write-tree) -m Snapshot -p HEAD) && git show --stat snapshot'
  248. $(git_conf) alias.snap snapshot
  249. $(git_conf) alias.setcmd '! f(){ git config alias.$$1 "! $$2"; }; f'
  250. $(git_conf) alias.make '!make'
  251. $(git_conf) alias.e '!env' # Run command in repository root
  252. #$(git_conf) alias.wc "!git ls-files -z | xargs -0 wc"
  253. # $(git_conf) push.default "simple"
  254. ifneq (,$(iswindows))
  255. $(git_conf) core.fileMode false
  256. endif
  257. endif
  258. # setup rc files
  259. # --------------
  260. # Generate load codes from the files themselves.
  261. # Load codes are defined by following SETUP_LOAD: indicator.
  262. # String DOTFILES_DIR in the load codes will be replaced into the value of
  263. # $(dotfiles_dir).
  264. # The load codes are appended to $(topfile).
  265. setup_rcs := setup-rc-vimrc setup-rc-tmux.conf setup-rc-emacs.el
  266. setup-rc: $(setup_rcs) ## Setup initialize files
  267. .PHONY: $(setup_rcs)
  268. setup-rc-vimrc: $(home)/.vimrc
  269. setup-rc-tmux.conf: $(home)/.tmux.conf
  270. setup-rc-emacs.el: $(home)/.emacs.d/init.el
  271. $(home)/.emacs.d/init.el: $(dotfiles_dir)/emacs.el $(home) $(home)/.emacs.d
  272. $(home)/.vimrc: $(dotfiles_dir)/vimrc $(home)
  273. $(home)/.tmux.conf: $(dotfiles_dir)/tmux.conf $(home)
  274. command_extract_setup_load := $(grep) -e 'SETUP_LOAD: ' | \
  275. sed -e 's/^.*SETUP_LOAD: //' -e 's|DOTFILES_DIR|$(dotfiles_dir)|'
  276. setup_rc_marker := ADDED BY 10sr_dotfiles/Makefile
  277. $(home)/.emacs.d/init.el $(home)/.vimrc $(home)/.tmux.conf:
  278. set -x; if ! $(grep) "$(setup_rc_marker)" "$@"; \
  279. then \
  280. (echo $(line_comment) $(setup_rc_marker); cat "$<" | $(command_extract_setup_load)) \
  281. | tee -a "$@"; \
  282. fi
  283. $(home)/.emacs.d/init.el: line_comment := ';;'
  284. $(home)/.vimrc: line_comment := '"'
  285. $(home)/.tmux.conf: line_comment := '\#'
  286. # run
  287. # ===
  288. run-emacs: $(home)/.emacs.d/init.el
  289. test -n "$(emacs)" && $(emacs) -q \
  290. --eval "(setq user-emacs-directory \"$(home)/.emacs.d/\")" --load "$<"
  291. # test
  292. # ====
  293. test_els := test-el-emacs.el
  294. test-el: $(test_els)
  295. .PHONY: $(test_els)
  296. $(test_els): test-el-%: $(dotfiles_dir)/% $(home)
  297. test -n "$(emacs)" && \
  298. $(emacs) -Q -batch -f batch-byte-compile $<
  299. # EMACS_EL_DRY_RUN=t $(emacs) -q --debug-init --batch \
  300. # --eval "(setq debug-on-error t)" \
  301. # --eval "(setq user-emacs-directory \"$(home)/.emacs.d/\")" \
  302. # --load $<c --kill
  303. # test syntax
  304. # ===========
  305. test_syntax_shs := test-syntax-shrc test-syntax-profile
  306. test-syntax-sh: $(test_syntax_shs)
  307. .PHONY: $(test_syntax_shs)
  308. $(test_syntax_shs): test-syntax-%: $(dotfiles_dir)/%
  309. sh -ec 'for sh in $(shrc_loadables); do $$sh -n $<; done'
  310. test_syntax_els := test-syntax-emacs.el
  311. test-syntax-el: $(test_syntax_els)
  312. .PHONY: $(test_syntax_els)
  313. sexp_elisp_syntax_check := \
  314. (with-temp-buffer \
  315. (emacs-lisp-mode) \
  316. (insert-file-contents file) \
  317. (condition-case err \
  318. (check-parens) \
  319. (user-error \
  320. (error (format "%s:%d:%d:Unmatched brancet or quote" \
  321. file \
  322. (line-number-at-pos) \
  323. (- (point) (point-at-bol)))))))
  324. $(test_syntax_els): test-syntax-%: $(dotfiles_dir)/%
  325. test -n "$(emacs)" && \
  326. $(emacs) -Q --debug-init --batch \
  327. --eval '(let ((file "$<")) $(sexp_elisp_syntax_check))' --kill