A cli program to easily handle .gitignore files
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.

305 lines
12 KiB

  1. # Version 0.2
  2. # Copyright 2017-2019, Stephan Sokolow
  3. # --== Variables to be customized/overridden by the user ==--
  4. # The target for `cargo` commands to use and `install-rustup-deps` to install
  5. export CARGO_BUILD_TARGET := "x86_64-unknown-linux-gnu"
  6. # An easy way to override the `cargo` channel for just this project
  7. channel := "nightly"
  8. # Extra cargo features to enable
  9. features := ""
  10. # An easy place to modify the build flags used
  11. build_flags := ""
  12. # Example for OpenPandora cross-compilation
  13. # export CARGO_BUILD_TARGET = "arm-unknown-linux-gnueabi"
  14. # -- `build-dist` --
  15. # Set this to the cross-compiler's `strip` when cross-compiling
  16. strip_bin := "strip"
  17. # Flags passed to `strip_bin`
  18. strip_flags := "--strip-unneeded"
  19. # Set this if you need to override it for a cross-compiling `sstrip`
  20. sstrip_bin := "sstrip"
  21. # Example for OpenPandora cross-compilation
  22. # strip_bin = `echo $HOME/opt/pandora-dev/arm-2011.09/bin/pandora-strip`
  23. # -- `kcachegrind` --
  24. # Extra arguments to pass to [callgrind](http://valgrind.org/docs/manual/cl-manual.html).
  25. callgrind_args := ""
  26. # Temporary file used by `just kcachegrind`
  27. callgrind_out_file := "callgrind.out.justfile"
  28. # Set this to override how `kcachegrind` is called
  29. kcachegrind := "kcachegrind"
  30. # -- `install` and `uninstall` --
  31. # Where to `install` bash completions.
  32. # **You'll need to manually add some lines to source these files in `.bashrc.`**
  33. bash_completion_dir := "~/.bash_completion.d"
  34. # Where to `install` fish completions. You'll probably never need to change this.
  35. fish_completion_dir := "~/.config/fish/completions"
  36. # Where to `install` zsh completions.
  37. # **You'll need to add this to your `fpath` manually**
  38. zsh_completion_dir := "~/.zsh/functions"
  39. # Where to `install` manpages. As long as `~/.cargo/bin` is in your `PATH`, `man` should
  40. # automatically pick up this location.
  41. manpage_dir := "~/.cargo/share/man/man1"
  42. # --== Code Begins ==--
  43. # Internal variables
  44. # TODO: Look up that GitHub issues post on whitespace handling
  45. _cargo_cmd := "cargo" # Used for --dry-run simulation
  46. _cargo := _cargo_cmd + " \"+" + channel + "\""
  47. _build_flags := "--features=\"" + features + "\" " + build_flags
  48. _doc_flags := "--document-private-items --features=\"" + features + "\""
  49. # Parse the value of the "name" key in the [package] section of Cargo.toml
  50. # using only the commands any POSIX-compliant platform should have
  51. # Source: http://stackoverflow.com/a/40778047/435253
  52. export _pkgname:=`sed -nr "/^\[package\]/ { :l /^name[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" Cargo.toml | sed 's@^"\(.*\)"$@\1@'`
  53. export _rls_bin_path:="target/" + CARGO_BUILD_TARGET + "/release/" + _pkgname
  54. export _dbg_bin_path:="target/" + CARGO_BUILD_TARGET + "/debug/" + _pkgname
  55. # Shorthand for `just test`
  56. DEFAULT: test
  57. # -- Development --
  58. # Alias for cargo-edit's `cargo add` which regenerates local API docs afterwards
  59. add +args="":
  60. {{_cargo}} add {{args}}
  61. just doc
  62. # Alias for `cargo bloat`
  63. bloat +args="":
  64. {{_cargo}} bloat {{_build_flags}} {{args}}
  65. # Alias for `cargo check`
  66. check +args="":
  67. {{_cargo}} check {{_build_flags}} {{args}}
  68. # Superset of `cargo clean -v` which deletes other stuff this justfile builds
  69. clean +args="":
  70. {{_cargo}} clean -v {{args}}
  71. export CARGO_TARGET_DIR:="target/kcov" && {{_cargo}} clean -v
  72. rm -rf dist
  73. # Run rustdoc with `--document-private-items` and then run cargo-deadlinks
  74. doc +args="":
  75. {{_cargo}} doc {{_doc_flags}} {{args}} && \
  76. {{_cargo}} deadlinks --dir target/$CARGO_BUILD_TARGET/doc/{{_pkgname}}
  77. # Alias for `cargo +nightly fmt -- {{args}}`
  78. fmt +args="":
  79. {{_cargo_cmd}} +nightly fmt -- {{args}}
  80. # Alias for `cargo +nightly fmt -- --check {{args}}` which un-bloats TODO/FIXME warnings
  81. fmt-check +args="":
  82. cargo +nightly fmt -- --check --color always {{args}} 2>&1 | egrep -v '[0-9]*[ ]*\|'
  83. # Run a debug build under [callgrind](http://valgrind.org/docs/manual/cl-manual.html), then open the
  84. # profile in [KCachegrind](https://kcachegrind.github.io/)
  85. kcachegrind +args="":
  86. {{_cargo}} build
  87. rm -rf '{{ callgrind_out_file }}'
  88. valgrind --tool=callgrind --callgrind-out-file='{{ callgrind_out_file }}' \
  89. {{ callgrind_args }} 'target/{{ CARGO_BUILD_TARGET }}/debug/{{ _pkgname }}' \
  90. '{{ args }}' || true
  91. test -e '{{ callgrind_out_file }}'
  92. {{kcachegrind}} '{{ callgrind_out_file }}'
  93. # Generate a statement coverage report in `target/cov/`
  94. kcov:
  95. #!/bin/sh
  96. # Adapted from:
  97. # - http://sunjay.ca/2016/07/25/rust-code-coverage
  98. # - https://users.rust-lang.org/t/tutorial-how-to-collect-test-coverages-for-rust-project/650
  99. #
  100. # As of July 2, 2016, there is no option to make rustdoc generate a runnable
  101. # test executable. That means that documentation tests will not show in your
  102. # coverage data. If you discover a way to run the doctest executable with kcov,
  103. # please open an Issue and we will add that to these instructions.
  104. # -- https://github.com/codecov/example-rust
  105. # Ensure that kcov can see totally unused functions without clobbering regular builds
  106. # Adapted from:
  107. # - http://stackoverflow.com/a/38371687/435253
  108. # - https://gist.github.com/dikaiosune/07177baf5cea76c27783efa55e99da89
  109. export CARGO_TARGET_DIR:="target/kcov"
  110. export RUSTFLAGS:='-C link-dead-code'
  111. kcov_path="$CARGO_TARGET_DIR/html"
  112. if [ "$#" -gt 0 ]; then shift; fi # workaround for "can't shift that many" being fatal in dash
  113. cargo test --no-run || exit $?
  114. rm -rf "$kcov_path"
  115. for file in "$CARGO_TARGET_DIR"/"$CARGO_BUILD_TARGET"/debug/$_pkgname-*; do
  116. if [ -x "$file" ]; then
  117. outpath="$kcov_path/$(basename "$file")"
  118. mkdir -p "$outpath"
  119. kcov --exclude-pattern=/.cargo,/usr/lib --verify "$outpath" "$file" "$@"
  120. elif echo "$file" | grep -F -e '-*'; then
  121. echo "No build files found for coverage!"
  122. exit 1
  123. fi
  124. done
  125. # Alias for cargo-edit's `cargo rm` which regenerates local API docs afterwards
  126. rm +args="":
  127. {{_cargo}} rm {{args}}
  128. just doc
  129. # Convenience alias for opening a crate search on lib.rs in the browser
  130. search +args="":
  131. xdg-open "https://lib.rs/search?q={{args}}"
  132. # Run all installed static analysis, plus `cargo test`
  133. test:
  134. @echo "============================= Outdated Packages ============================="
  135. @{{_cargo}} outdated
  136. @echo "\n============================= Insecure Packages ============================="
  137. @{{_cargo}} audit -q
  138. @echo "\n=============================== Clippy Lints ================================"
  139. @{{_cargo}} clippy -q {{_build_flags}}
  140. @echo "\n===================== Dead Internal Documentation Links ====================="
  141. @{{_cargo}} doc -q --document-private-items {{_build_flags}} && \
  142. {{_cargo}} deadlinks --dir target/$CARGO_BUILD_TARGET/doc/{{_pkgname}}
  143. @echo "\n================================ Test Suite ================================="
  144. @{{_cargo}} test -q {{_build_flags}}
  145. @echo "============================================================================="
  146. # Alias for cargo-edit's `cargo update` which regenerates local API docs afterwards
  147. update +args="":
  148. {{_cargo}} update {{args}}
  149. just doc
  150. # TODO: https://users.rust-lang.org/t/howto-sanitize-your-rust-code/9378
  151. # -- Local Builds --
  152. # Alias for `cargo build`
  153. build:
  154. @echo "\n--== Building with {{channel}} for {{CARGO_BUILD_TARGET}} (features: {{features}}) ==--\n"
  155. {{_cargo}} build {{_build_flags}}
  156. # Install the un-packed binary, shell completions, and a manpage
  157. install: dist-supplemental
  158. @# Install completions
  159. @# NOTE: bash and zsh completion requires additional setup to source a non-root dir
  160. mkdir -p {{bash_completion_dir}} {{zsh_completion_dir}} {{ fish_completion_dir }} {{ manpage_dir }}
  161. cp dist/{{ _pkgname }}.bash {{ bash_completion_dir }}/{{ _pkgname }}
  162. cp dist/{{ _pkgname }}.zsh {{ zsh_completion_dir }}/_{{ _pkgname }}
  163. cp dist/{{ _pkgname }}.fish {{ fish_completion_dir }}/{{ _pkgname }}.fish
  164. @# Install the manpage
  165. cp dist/{{ _pkgname }}.1.gz {{ manpage_dir }}/{{ _pkgname }}.1.gz || true
  166. @# Install the command to ~/.cargo/bin
  167. {{_cargo}} install --path . --force --features="{{features}}"
  168. # Alias for `cargo run -- {{args}}`
  169. run +args="":
  170. {{_cargo}} run {{_build_flags}} -- {{args}}
  171. # Remove any files installed by the `install` task (but leave any parent directories created)
  172. uninstall:
  173. @# TODO: Implement the proper fallback chain from `cargo install`
  174. rm ~/.cargo/bin/{{ _pkgname }} || true
  175. rm {{ manpage_dir }}/{{ _pkgname }}.1.gz || true
  176. rm {{ bash_completion_dir }}/{{ _pkgname }} || true
  177. rm {{ fish_completion_dir }}/{{ _pkgname }}.fish || true
  178. rm {{ zsh_completion_dir }}/_{{ _pkgname }} || true
  179. # -- Release Builds --
  180. # Make a release build and then strip and compress the resulting binary
  181. build-dist:
  182. @echo "\n--== Building with {{channel}} for {{CARGO_BUILD_TARGET}} (features: {{features}}) ==--\n"
  183. {{_cargo}} build --release {{_build_flags}}
  184. @# Don't modify the original "cargo" output. That confuses cargo somehow.
  185. cp "{{_rls_bin_path}}" "{{_rls_bin_path}}.stripped"
  186. @printf "\n--== Stripping, SStripping, and Compressing With UPX ==--\n"
  187. {{strip_bin}} {{strip_flags}} "{{_rls_bin_path}}.stripped"
  188. @# Allow sstrip to fail because it can't be installed via "just install-deps"
  189. {{sstrip_bin}} "{{_rls_bin_path}}.stripped" || true
  190. @# Display the resulting file sizes so we can keep an eye on them
  191. @# (Separate `ls` invocations are used to force the display ordering)
  192. @printf "\n--== Final Result ==--\n"
  193. @ls -1sh "{{_rls_bin_path}}"
  194. @ls -1sh "{{_rls_bin_path}}.stripped"
  195. @printf "\n"
  196. # Build the shell completions and a manpage, and put them in `dist/`
  197. dist-supplemental:
  198. mkdir -p dist
  199. @# Generate completions and store them in dist/
  200. {{_cargo}} run --release {{_build_flags}} -- dump-completions bash > dist/{{ _pkgname }}.bash
  201. {{_cargo}} run --release {{_build_flags}} -- dump-completions zsh > dist/{{ _pkgname }}.zsh
  202. {{_cargo}} run --release {{_build_flags}} -- dump-completions fish > dist/{{ _pkgname }}.fish
  203. {{_cargo}} run --release {{_build_flags}} -- dump-completions elvish > dist/{{ _pkgname }}.elvish
  204. {{_cargo}} run --release {{_build_flags}} -- dump-completions powershell > dist/{{ _pkgname }}.powershell
  205. @# Generate manpage and store it gzipped in dist/
  206. @# (This comes last so the earlier calls to `cargo run` will get the compiler warnings out)
  207. help2man -N '{{_cargo}} run {{_build_flags}} --' \
  208. | gzip -9 > dist/{{ _pkgname }}.1.gz || true
  209. # Call `dist-supplemental` and `build-dist` and copy the packed binary to `dist/`
  210. dist: build-dist dist-supplemental
  211. @# Copy the packed command to dist/
  212. cp "{{ _rls_bin_path }}.stripped" dist/{{ _pkgname }}
  213. # -- Dependencies --
  214. # Use `apt-get` to install dependencies `cargo` can't (except `kcov` and `sstrip`)
  215. install-apt-deps:
  216. sudo apt-get install binutils help2man kcachegrind upx valgrind
  217. # `install-rustup-deps` and then `cargo install` tools
  218. install-cargo-deps: install-rustup-deps
  219. @# Prevent "already installed" from causing a failure
  220. {{_cargo}} install cargo-audit || true
  221. {{_cargo}} install cargo-bloat || true
  222. {{_cargo}} install cargo-deadlinks || true
  223. {{_cargo}} install cargo-edit || true
  224. {{_cargo}} install cargo-outdated || true
  225. cargo +nightly install cargo-cov || true
  226. # Install (don't update) nightly and `channel` toolchains, plus `CARGO_BUILD_TARGET`, clippy, and rustfmt
  227. install-rustup-deps:
  228. @# Prevent this from gleefully doing an unwanted "rustup update"
  229. rustup toolchain list | grep -q '{{channel}}' || rustup toolchain install '{{channel}}'
  230. rustup toolchain list | grep -q nightly || rustup toolchain install nightly
  231. rustup target list | grep -q '{{CARGO_BUILD_TARGET}} (' || rustup target add '{{CARGO_BUILD_TARGET}}'
  232. rustup component list | grep -q 'clippy-\S* (' || rustup component add clippy
  233. rustup component list --toolchain nightly | grep 'rustfmt-\S* (' || rustup component add rustfmt --toolchain nightly
  234. # Run `install-apt-deps` and `install-cargo-deps`. List what remains.
  235. @install-deps: install-apt-deps install-cargo-deps
  236. echo
  237. echo "-----------------------------------------------------------"
  238. echo "IMPORTANT: You will need to install the following manually:"
  239. echo "-----------------------------------------------------------"
  240. echo " * Rust-compatible kcov (http://sunjay.ca/2016/07/25/rust-code-coverage)"
  241. echo " * sstrip (http://www.muppetlabs.com/%7Ebreadbox/software/elfkickers.html)"
  242. # Local Variables:
  243. # mode: makefile
  244. # End:
  245. # vim: set ft=make textwidth=100 colorcolumn=101 noexpandtab sw=8 sts=8 ts=8 :