Simple Makefile target helper https://pagure.io/mkit

newstub 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. #!/bin/bash
  2. # mkit - simple install helper
  3. # See LICENSE file for copyright and license details.
  4. init_core() {
  5. #
  6. # Load core modules (or die)
  7. #
  8. #shellcheck disable=SC1090
  9. . "$MKIT_DIR/include/mkit.sh" \
  10. && . "$MKIT_DIR/include/vars.sh" \
  11. && return 0
  12. echo "failed to load core; check if MKIT_DIR is set properly: $MKIT_DIR" >&2
  13. exit 9
  14. }
  15. #
  16. # Path to MKit dir (where 'include' is)
  17. #
  18. MKIT_DIR=${MKIT_DIR:-$(dirname "$0")}
  19. init_core
  20. declare -A MKIT_INIT_LICENSES
  21. MKIT_INIT_LICENSES[GPLv1]="http://www.gnu.org/licenses/old-licenses/gpl-1.0.md"
  22. MKIT_INIT_LICENSES[GPLv2]="http://www.gnu.org/licenses/old-licenses/gpl-2.0.md"
  23. MKIT_INIT_LICENSES[GPLv3]="http://www.gnu.org/licenses/gpl-3.0.md"
  24. MKIT_INIT_LICENSES[LGPLv2]="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.md"
  25. MKIT_INIT_LICENSES[LGPLv3]="http://www.gnu.org/licenses/lgpl-3.0.md"
  26. MKIT_INIT_LICENSES[AGPLv3]="http://www.gnu.org/licenses/agpl-3.0.md"
  27. MKIT_INIT_LICENSES[FDLv1.3]="http://www.gnu.org/licenses/fdl-1.3.md"
  28. MKIT_INIT_LICENSES[FDLv1.2]="http://www.gnu.org/licenses/old-licenses/fdl-1.2.md"
  29. MKIT_INIT_LICENSES[FDLv1.1]="http://www.gnu.org/licenses/old-licenses/fdl-1.1.md"
  30. deploy() {
  31. local file=$1 # which known file?
  32. local any_name=${NiceName:-$PackageName}
  33. mkdir -p "$(dirname "$file")"
  34. case $file in
  35. Makefile)
  36. echo -n "# $any_name"
  37. test -n "$Tagline" && echo -n " - $Tagline"
  38. echo
  39. echo '# See LICENSE.md file for copyright and license details.'
  40. echo ''
  41. echo 'MKIT_DIR=utils/mkit'
  42. #shellcheck disable=SC2016
  43. echo 'include $(MKIT_DIR)/mkit.mk'
  44. ;;
  45. README.md)
  46. echo "$any_name"
  47. tr -c '=\n' '=' <<<"$any_name"
  48. echo ''
  49. echo ''
  50. if test -n "$Tagline"; then
  51. echo "$Tagline"
  52. else
  53. echo "(Nothing to say about this project.)"
  54. fi
  55. ;;
  56. mkit.ini)
  57. echo "[project]"
  58. echo " version = 0.0.0"
  59. test -n "$Codename" && echo " codename = $Codename"
  60. test -n "$NiceName" && echo " name = $NiceName"
  61. test -n "$Tagline" && echo " tagline = $Tagline"
  62. test -n "$PackageName" && echo " pkgname = $PackageName"
  63. test -n "$Maintainer" && echo " maintainer = $Maintainer"
  64. test -n "$VcsBrowser" && echo " vcs_browser = $VcsBrowser"
  65. test -n "$RelSrc" && echo " relsrc = $RelSrc"
  66. test -n "$RelDst" && echo " reldst = $RelDst"
  67. echo ""
  68. echo "[dist]"
  69. echo " tarball = LICENSE.md"
  70. $MkMakefile && echo " tarball = Makefile"
  71. $MkReadme && echo " tarball = README.md"
  72. echo " tarball = mkit.ini"
  73. $MkPackaging && echo " tarball = packaging"
  74. echo " tarball = src"
  75. echo " tarball = tests"
  76. echo " tarball = utils"
  77. $MkPackaging && echo " rpmstuff = packaging/template.spec"
  78. $MkPackaging && echo " debstuff = packaging/debian"
  79. echo ""
  80. echo "[ENV]"
  81. echo " PREFIX = /usr/local"
  82. echo ""
  83. echo "[roots]"
  84. echo " bin = [ENV:PREFIX]/bin"
  85. echo " doc = [ENV:PREFIX]/share/doc/$PackageName"
  86. echo ""
  87. echo "[tokens]"
  88. echo " __BIN_DIR__ = [roots:bin]"
  89. echo ""
  90. echo "[modes]"
  91. echo " bin = 755"
  92. echo " doc = 644"
  93. echo ""
  94. echo "[files]"
  95. echo " bin = src/$PackageName"
  96. $MkLicense && echo " doc = LICENSE.md"
  97. $MkReadme && echo " doc = README.md"
  98. echo ""
  99. echo "#mkit version=$MKIT_VERSION"
  100. ;;
  101. packaging/template.spec)
  102. echo 'Name: __MKIT_PROJ_PKGNAME__'
  103. echo 'Version: __MKIT_PROJ_VERSION__'
  104. echo 'Release: 1%{?dist}'
  105. echo 'Summary: __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
  106. echo ''
  107. $MkLicense && echo "License: $License"
  108. echo 'Source0: %{name}-%{version}.tar.gz'
  109. echo ''
  110. echo 'BuildArch: noarch'
  111. echo 'BuildRequires: coreutils git'
  112. echo 'Requires: MKIT_NEWSTUB_REQUIRES'
  113. echo ''
  114. echo '%description'
  115. echo 'MKIT_NEWSTUB_DESCRIPTION'
  116. echo ''
  117. echo '%prep'
  118. echo '%setup -q'
  119. echo ''
  120. echo '%build'
  121. echo 'make %{?_smp_mflags}'
  122. echo ''
  123. echo '%install'
  124. echo '%make_install'
  125. echo ''
  126. echo '%files'
  127. echo 'MKIT_NEWSTUB_FILELIST'
  128. echo ''
  129. echo '%changelog'
  130. echo ''
  131. echo '# specfile built with MKit __MKIT_SELF_VERSION__'
  132. ;;
  133. packaging/debian/copyright)
  134. echo ""
  135. ;;
  136. packaging/debian/control)
  137. echo 'Source: __MKIT_PROJ_PKGNAME__'
  138. echo 'Maintainer: __MKIT_PROJ_MAINTAINER__'
  139. test -n "$VcsBrowser" && echo 'Vcs-Browser: __MKIT_PROJ_VCS_BROWSER__'
  140. echo 'Section: misc'
  141. echo 'Priority: extra'
  142. echo 'Standards-Version: 3.9.2'
  143. echo 'Build-Depends: debhelper (>= 9)'
  144. echo ''
  145. echo 'Package: __MKIT_PROJ_PKGNAME__'
  146. echo 'Architecture: all'
  147. echo 'Depends: MKIT_NEWSTUB_REQUIRES'
  148. echo 'Description: __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
  149. echo ' MKIT_NEWSTUB_DESCRIPTION'
  150. echo ''
  151. echo '# control file built with MKit __MKIT_SELF_VERSION__'
  152. ;;
  153. packaging/debian/changelog)
  154. echo '__MKIT_PROJ_PKGNAME__ (__MKIT_PROJ_VERSION__-1) UNRELEASED; urgency=medium'
  155. echo ''
  156. echo ' * Initial release. (Closes: #XXXXXX)'
  157. echo ''
  158. echo " -- __MKIT_PROJ_MAINTAINER__ $(date -R)"
  159. ;;
  160. packaging/debian/compat)
  161. echo 9
  162. ;;
  163. packaging/debian/rules)
  164. echo '#!/usr/bin/make -f'
  165. echo ''
  166. echo '%:'
  167. echo ''
  168. echo ' dh $@'
  169. echo ''
  170. echo 'override_dh_auto_install:'
  171. echo ''
  172. echo ' make install DESTDIR=debian/tmp'
  173. echo ''
  174. echo 'override_dh_usrlocal:'
  175. echo ''
  176. echo ' @true'
  177. ;;
  178. packaging/debian/source/format)
  179. echo '3.0 (quilt)'
  180. ;;
  181. packaging/debian/*.install)
  182. echo MKIT_NEWSTUB_FILELIST
  183. ;;
  184. src/*.skel)
  185. echo 'echo "my version is: __MKIT_PROJ_VERSION__"'
  186. echo 'echo "And that'"'"'s all, folks!"'
  187. ;;
  188. LICENSE.md)
  189. local url # license URL
  190. url="${MKIT_INIT_LICENSES[$License]}"
  191. curl -sf "$url" \
  192. || die "failed to download license: $url"
  193. ;;
  194. .mkit/autoclean)
  195. ;;
  196. MKIT_NEWSTUB_README.md)
  197. echo "FINISHING MKIT CONFIGURATION"
  198. echo "============================"
  199. echo ""
  200. echo "Congratulations, your new project has been configured!"
  201. echo ""
  202. echo "However, the *newstub* script is not able to figure out"
  203. echo "everything, so few things still need to be done manually."
  204. echo "This document will guide you throught the rest of the"
  205. echo "process."
  206. echo ""
  207. echo ""
  208. echo "Structure"
  209. echo "---------"
  210. echo ""
  211. echo "First, let's go through the directory structure:"
  212. echo ""
  213. echo " * *src* directory - here is your main place to store"
  214. echo " source files. This includes also documents like user"
  215. echo " manuals---IOW, anything intended to end up on user's"
  216. echo " machine should be uder 'src'."
  217. echo ""
  218. echo " Note that during build time, files named ending with"
  219. echo " '.skel' are subject to token expansion, see mkit.ini"
  220. echo " section below for details."
  221. echo ""
  222. echo " * *notes* directory - here you shall store notes"
  223. echo " intended for people contributing to your project,"
  224. echo " for instance, guidelines, coding style documents,"
  225. echo " TODOs, ideas, plans..."
  226. echo ""
  227. echo " * *utils* directory - here you shall store utilities"
  228. echo " and scripts that will help you with project maintenance,"
  229. echo " and that, unlike software like compilers or versioning"
  230. echo " systems, can (and should) be embedded inside the"
  231. echo " repository."
  232. echo ""
  233. echo " MKit itself is one nice example. :)"
  234. if $MkPackaging; then
  235. echo ""
  236. echo " * *packaging* directory contains templates that enable"
  237. echo " MKit create raw stuffs used to create DEB or RPM"
  238. echo " packages. Similar to '.skel' files in 'src', all files"
  239. echo " here are automatically considered for token expansion,"
  240. echo " no matter how they are named (see mkit.ini section"
  241. echo " below)."
  242. echo ""
  243. echo " NOTE: these templates, as well as any packages created by"
  244. echo " them are intended only for experimental, private use and"
  245. echo " testing."
  246. echo ""
  247. echo " Should you have ambition to create 'real' packages for"
  248. echo " OS distribution such as Debian or Fedora (what a great"
  249. echo " idea!), be prepared that you will need to follow their"
  250. echo " guidelines. This will most probably mean huge changes"
  251. echo " to these packages or even changes to your workflow."
  252. echo ""
  253. echo ""
  254. echo "Placeholders"
  255. echo "------------"
  256. echo ""
  257. echo "At places where *newstub* script did not have way to get all"
  258. echo "information automatically, it has inserted placeholders."
  259. echo "You will need to go through all of these placeholders and"
  260. echo "replace them with proper data."
  261. echo ""
  262. echo "Please follow instructions:"
  263. echo ""
  264. echo " 1. Look for placeholders starting with \`MKIT_NEWSTUB_\`"
  265. echo " prefix by calling this command:"
  266. echo ""
  267. echo " grep -lw MKIT_NEWSTUB_ -r"
  268. echo ""
  269. echo " 2. Go through each file and locate the placeholder. (You"
  270. echo " will also see placeholders like \`__MKIT_*__\`, you can"
  271. echo " ignore those."
  272. echo ""
  273. echo " 3. Replace placeholder with appropriate information:"
  274. echo ""
  275. echo " * \`MKIT_NEWSTUB_REQUIRES\` - Requirements of your"
  276. echo " project."
  277. echo ""
  278. echo " * \`MKIT_NEWSTUB_DESCRIPTION\` - Description of your"
  279. echo " project (few sentences to paragraphs)."
  280. echo ""
  281. echo " * \`MKIT_NEWSTUB_FILELIST\` - List of full paths to"
  282. echo " your files after installation."
  283. echo ""
  284. echo " Refer to these documents for further details:"
  285. echo ""
  286. echo " http://rpm-guide.readthedocs.io/"
  287. echo " https://www.debian.org/doc/manuals/maint-guide/"
  288. fi
  289. echo ""
  290. echo ""
  291. echo "mkit.ini"
  292. echo "--------"
  293. echo ""
  294. echo "Most sections still need to be reviewed. In order to do"
  295. echo "that, you will need to understand how MKit works:"
  296. echo ""
  297. echo " 1. First, you need to define *roles* your files will play"
  298. echo " when they are installed on user's file systems. These"
  299. echo " roles then imply where and how the files should be"
  300. echo " deployed."
  301. echo ""
  302. echo " Typical example of a role is e.g. 'bin' for commands"
  303. echo " (normally under '/usr/bin' or '/usr/local/bin'), 'doc'"
  304. echo " for documents or 'lib' for libraries."
  305. echo ""
  306. echo " 2. Next, in \`[roots]\` section, you have to set target"
  307. echo " root directory for each role. However, in order to"
  308. echo " enable people to implement local conventions, it is"
  309. echo " considered a good manner to also respect PREFIX"
  310. echo " environment variable. For this reason, most paths"
  311. echo " need to start with \`[ENV:PREFIX]\`."
  312. echo ""
  313. echo " 3. \`[files]\` section is where you assign actual files"
  314. echo " from your repository to their final paths. The format"
  315. echo " is \`ROLE = REPOPATH [RENAMED]\`, where ROLE is file's"
  316. echo " role, REPOPATH is relative path to the file."
  317. echo ""
  318. echo " Final path is then composed by taking path assigned to"
  319. echo " ROLE and appending file's name. However, if you need"
  320. echo " the deployed file to have different name than in the"
  321. echo " codebase, you can specify the other name as RENAMED."
  322. echo ""
  323. echo " Note that you don't need to address every single file"
  324. echo " individually, if in your repo you have a directory with"
  325. echo " 100 files of the same role, you can add just path to the"
  326. echo " directory itself."
  327. echo ""
  328. echo " 4. If some roles require special permissions on your files,"
  329. echo " \`[modes]\` section is your friend. Permissions here"
  330. echo " should be in UNIX octal format."
  331. echo ""
  332. echo " 5. Next, \`[tokens]\` section allows you to define own"
  333. echo " placeholders that will be replaced when your scripts are"
  334. echo " built. Each file in 'src' directory that is named with"
  335. echo " '.skel' suffix, and each file from 'packaging' directory"
  336. echo " (no matter its name), can contain one or more of tokens"
  337. echo " defined here, plus range of tokens automatically defined"
  338. echo " by MKit. During build, these tokens are replaced with"
  339. echo " their actual values."
  340. echo ""
  341. echo " 6. Less interesting, but important section is \`[dist]\`,"
  342. echo " which lists files in your codebase that will be added"
  343. echo " to distribution tarball (part of \"stuffs\" mentioned"
  344. echo " above). Listing directory here will include all its"
  345. echo " contents, and normally it's OK to be very inclusive, so"
  346. echo " most of the time this section should be OK."
  347. echo ""
  348. echo " 7. Even less interesting is section \`[ENV]\`. It is"
  349. echo " special in that it provides *default* value for an"
  350. echo " environment variable. You almost never need to touch"
  351. echo " this."
  352. echo ""
  353. echo " 8. Finally, the most interesting section! \`[project]\`,"
  354. echo " provides most general information for your project such"
  355. echo " as name and version."
  356. echo ""
  357. echo " Note that the \`version\` key is another \"special"
  358. echo " snowflake\" -- it is now set to 0.0.0, and you **should"
  359. echo " not need** to change it manually. When you feel you"
  360. echo " a are ready to release next version of your evolving"
  361. echo " project, simply call \`make vbump\` and MKit will take"
  362. echo " care of everything!"
  363. if $MkMakefile; then
  364. echo ""
  365. echo ""
  366. echo "Makefile"
  367. echo "--------"
  368. echo ""
  369. echo "*newstub* script also created a Makefile for you, but all"
  370. echo "it really does is include MKit's own mkit.mk, which in turn"
  371. echo "only maps \`make\` targets to actual mkit script calls."
  372. echo "Unless your project already uses GNU Make, you should not"
  373. echo "need to change this file."
  374. fi
  375. if $MkReadme; then
  376. echo ""
  377. echo ""
  378. echo "README.md"
  379. echo "---------"
  380. echo ""
  381. echo "Each serious project needs a serious README. Which is why"
  382. echo "*newstub* has created a 'stub' of one for you."
  383. fi
  384. echo ""
  385. echo ""
  386. echo "The final touch"
  387. echo "---------------"
  388. echo ""
  389. echo "Once you have reviewed everything, just delete this file!"
  390. ;;
  391. esac >"$file"
  392. }
  393. known_licenses() {
  394. local key
  395. local first=true
  396. for key in "${!MKIT_INIT_LICENSES[@]}"; do
  397. $first && echo "$key" && continue
  398. echo ", $key"
  399. done
  400. }
  401. usage() {
  402. {
  403. echo "Usage:"
  404. echo " newstub [options] NAME"
  405. echo " newstub -L"
  406. echo ""
  407. echo "Options:"
  408. echo ""
  409. echo " -c CODENAME your project codename"
  410. echo " -t TAGLINE your project tagline"
  411. echo " -b RELSRC pre-release branch"
  412. echo " -B RELDST post-release branch"
  413. echo " -n NICENAME your project's 'nice' name"
  414. echo " -l LICENSE your options's license (see -L)"
  415. echo " -m MAINT project maintainer's name and e-mail"
  416. echo " -v URL URL to public code browser"
  417. echo " -a enable autoclean ('make clean' after"
  418. echo " each 'make install')"
  419. echo " -g make git commits before and adter"
  420. echo " (implies -y)"
  421. echo " -y don't ask, just do it"
  422. echo " -R skip creating README.md"
  423. echo " -M skip creating Makefile"
  424. echo " -P skip creating packaging templates"
  425. echo " -L list know licenses and exit"
  426. echo ""
  427. echo "NAME should be packaging-friendly name, ie. consist"
  428. echo "only of small letters, numbers, underscore and dash."
  429. echo "For your 'real' name, use NICENAME, which can be any"
  430. echo "string."
  431. } >&2
  432. exit 2
  433. }
  434. confirm() {
  435. local response # user's response to our warning
  436. $Force && return 0
  437. {
  438. echo "Warning: This operation can be destructive for your"
  439. echo "current codebase. At least following files will be"
  440. echo "created or overwritten:"
  441. echo ""
  442. $MkPackaging && echo " * 'packaging' directory (pass -P to avoid)"
  443. $MkMakefile && echo " * 'Makefile' (pass -M to avoid)"
  444. $MkReadme && echo " * 'README.md' (pass -R to avoid)"
  445. $MkLicense && echo " * 'LICENSE.md' (omit -l to avoid)"
  446. echo " * 'mkit.ini'"
  447. echo ""
  448. read -p "Type 'yes' to proceed: " -r response
  449. } >&2
  450. test "$response" == "yes" && return 0
  451. warn "Aborting."
  452. return 1
  453. }
  454. mkcommit_backup() {
  455. git ls-files --others \
  456. | grep -qv -e '^utils/mkit$' -e '^utils/mkit/' \
  457. || { warn "nothing to back up"; return 0; }
  458. git add . || return
  459. git rm -r --cached utils/mkit || return
  460. git commit -m "WIP [mkit/newstub] backup" || return
  461. }
  462. mkcommit_mkit_code() {
  463. git ls-files --others \
  464. | grep -q -e '^utils/mkit$' -e '^utils/mkit/' \
  465. || return 0
  466. git add utils/mkit || return
  467. git commit -m "WIP [mkit/newstub] Add MKit version v$MKIT_VERSION" || return
  468. }
  469. mkcommit_mkit_conf() {
  470. git add . || return
  471. git commit -m "WIP [mkit/newstub] Add MKit configuration stub" || return
  472. }
  473. deploy_packaging() {
  474. rm -rf packaging
  475. deploy packaging/template.spec
  476. deploy packaging/debian/copyright
  477. deploy packaging/debian/control
  478. deploy packaging/debian/changelog
  479. deploy packaging/debian/compat
  480. deploy packaging/debian/rules
  481. deploy packaging/debian/source/format
  482. deploy packaging/debian/"$PackageName".install
  483. deploy packaging/template.spec
  484. }
  485. main() {
  486. local NiceName # human-readable project name
  487. local PackageName # machine-safe project (package) name
  488. local RelSrc # pre-release branch
  489. local RelDst # post-release branch
  490. local Codename # release codename
  491. local Tagline # project tagline
  492. local Maintainer # project maintainer (Name + e-mail)
  493. local VcsBrowser # VCS browser (eg. GitHub URL)
  494. local AutoClean=false # touch .mkit/autoclean?
  495. local MkCommits=false # create pre/post git commits?
  496. local Force=false # go without asking?
  497. local MkReadme=true # create README.md?
  498. local MkMakefile=true # create Makefile?
  499. local MkPackaging=true # create packaging templates?
  500. local MkLicense=false # create LICENSE.md file
  501. while true; do case $1 in
  502. -n) NiceName=$2; shift 2 || usage ;;
  503. -b) RelSrc=$2; shift 2 || usage ;;
  504. -B) RelDst=$2; shift 2 || usage ;;
  505. -c) Codename=$2; shift 2 || usage ;;
  506. -t) Tagline=$2; shift 2 || usage ;;
  507. -l) License=$2; shift 2 || usage ;;
  508. -m) Maintainer=$2; shift 2 || usage ;;
  509. -v) VcsBrowser=$2; shift 2 || usage ;;
  510. -M) MkMakefile=false; shift ;;
  511. -R) MkReadme=false; shift ;;
  512. -a) AutoClean=true; shift ;;
  513. -y) Force=true; shift ;;
  514. -g) MkCommits=true; shift ;;
  515. -P) MkPackaging=false; shift ;;
  516. -L) known_licenses | tr , '\n'; exit 0 ;;
  517. -*) usage ;;
  518. *) break ;;
  519. esac done
  520. PackageName="$1"
  521. test -n "$PackageName" || usage
  522. if test -n "$License"; then
  523. known_licenses | grep -qxF "$License" \
  524. || die "unknown license (use -L to get list): $License"
  525. MkLicense=true
  526. fi
  527. if $MkCommits; then
  528. mkcommit_backup || die "failed creating backup commit"
  529. Force=true
  530. fi
  531. confirm || return 1
  532. deploy mkit.ini
  533. deploy src/"$PackageName".skel
  534. $MkMakefile && deploy Makefile
  535. $MkReadme && deploy README.md
  536. $MkLicense && deploy LICENSE.md
  537. $AutoClean && deploy .mkit/autoclean
  538. $MkPackaging && deploy_packaging
  539. if $MkCommits; then
  540. mkcommit_mkit_code || die "failed creating post-commit"
  541. mkcommit_mkit_conf || die "failed creating post-commit"
  542. fi
  543. deploy MKIT_NEWSTUB_README.md
  544. warn "Configuration stub built, follow instructions in"
  545. warn "MKIT_NEWSTUB_README.md to finish configuration."
  546. return 0
  547. }
  548. main "$@"