reserve-cratesio-package-name.sh 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #!/usr/bin/env bash
  2. display_help() {
  3. local bin
  4. bin="$(basename --suffix='.sh' "$0")"
  5. cat <<EOF 1>&2
  6. $bin
  7. Reserve a Rust package name on crates.io
  8. USAGE:
  9. $bin [FLAGS] [OPTIONS] <TARGET_TYPE> <PACKAGE_NAME>
  10. FLAGS:
  11. --help Display this help message
  12. --no-prefix Do not require \`agave-\` or \`solana-\` prefix on PACKAGE_NAME
  13. --publish Upload the reserved package. Without this flag, a
  14. dry-run is performed
  15. OPTIONS:
  16. --token <TOKEN> Token used to authenticate with crates.io
  17. ARGS:
  18. TARGET_TYPE The package target type [possible values: bin, lib]
  19. PACKAGE_NAME The desired package name [see:
  20. https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field]
  21. EOF
  22. }
  23. require_prefix=true
  24. maybe_publish='--dry-run'
  25. positional=()
  26. while [[ -n "$1" ]]; do
  27. case "$1" in
  28. --)
  29. break
  30. ;;
  31. --help)
  32. display_help
  33. exit 0
  34. ;;
  35. --no-prefix)
  36. require_prefix=false
  37. ;;
  38. --publish)
  39. maybe_publish=''
  40. ;;
  41. --token)
  42. maybe_crates_token="--token $2"
  43. shift
  44. ;;
  45. --* | -*)
  46. echo "error: unexpected argument \`$1\`" 1>&2
  47. display_help
  48. exit 1
  49. ;;
  50. *)
  51. positional+=("$1")
  52. ;;
  53. esac
  54. shift
  55. done
  56. while [[ -n "$1" ]]; do
  57. positional+=("$1")
  58. shift
  59. done
  60. target_type="${positional[0]:?'TARGET_TYPE must be declared'}"
  61. package_name="${positional[1]:?'PACKAGE_NAME must be declared'}"
  62. case "${target_type}" in
  63. bin)
  64. src_filename='main.rs'
  65. src_file_body='fn main() {}'
  66. ;;
  67. lib)
  68. src_filename='lib.rs'
  69. src_file_body=''
  70. ;;
  71. *)
  72. echo "error: unexpected TARGET_TYPE: \`${target_type}\`" 1>&2
  73. display_help
  74. exit 1
  75. ;;
  76. esac
  77. if ! [[ "${package_name}" =~ ^[a-zA-Z0-9_-]{1,64} ]]; then
  78. echo "error: illegal PACKAGE_NAME: \`${package_name}\`" 1>&2
  79. display_help
  80. exit 1
  81. fi
  82. if ${require_prefix} && ! [[ "${package_name}" =~ ^(agave|solana)- ]]; then
  83. # shellcheck disable=SC2016 # backticks are not a command here
  84. echo 'error: PACKAGE_NAME MUST start with `agave-` or `solana-`' 1>&2
  85. display_help
  86. exit 1
  87. fi
  88. tmpdir="$(mktemp -d)"
  89. if pushd "${tmpdir}" &>/dev/null; then
  90. cat <<EOF > "Cargo.toml"
  91. [package]
  92. name = "${package_name}"
  93. version = "0.0.0"
  94. description = "reserved for future use"
  95. authors = ["Anza Maintainers <maintainers@anza.xyz>"]
  96. repository = "https://github.com/anza-xyz/agave"
  97. license = "Apache-2.0"
  98. homepage = "https://anza.xyz"
  99. documentation = "https://docs.rs/${package_name}"
  100. edition = "2021"
  101. EOF
  102. mkdir -p src
  103. echo "${src_file_body}" > "src/${src_filename}"
  104. # shellcheck disable=SC2086 # do not want to quote optional arg tokens
  105. cargo publish ${maybe_publish} ${maybe_crates_token}
  106. popd &>/dev/null || true
  107. fi
  108. rm -rf "${tmpdir}"