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.

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