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.

313 lines
12 KiB

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