imapfilter convenience wrapper

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  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,SC1091
  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. mkit_import ini
  21. declare -A MKIT_STUB_LICENSES
  22. MKIT_STUB_LICENSES[GPLv1]="http://www.gnu.org/licenses/old-licenses/gpl-1.0.md"
  23. MKIT_STUB_LICENSES[GPLv2]="http://www.gnu.org/licenses/old-licenses/gpl-2.0.md"
  24. MKIT_STUB_LICENSES[GPLv3]="http://www.gnu.org/licenses/gpl-3.0.md"
  25. MKIT_STUB_LICENSES[LGPLv2]="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.md"
  26. MKIT_STUB_LICENSES[LGPLv3]="http://www.gnu.org/licenses/lgpl-3.0.md"
  27. MKIT_STUB_LICENSES[AGPLv3]="http://www.gnu.org/licenses/agpl-3.0.md"
  28. MKIT_STUB_LICENSES[FDLv1.3]="http://www.gnu.org/licenses/fdl-1.3.md"
  29. MKIT_STUB_LICENSES[FDLv1.2]="http://www.gnu.org/licenses/old-licenses/fdl-1.2.md"
  30. MKIT_STUB_LICENSES[FDLv1.1]="http://www.gnu.org/licenses/old-licenses/fdl-1.1.md"
  31. deploy() {
  32. local file=$1 # which known file?
  33. local any_name=${NiceName:-$PackageName}
  34. local tmp
  35. tmp=$(mktemp -t mkit.stub.deploy.XXXXXXX)
  36. mkdir -p "$(dirname "$file")"
  37. case $file in
  38. Makefile)
  39. echo -n "# $any_name"
  40. test -n "$Tagline" && echo -n " - $Tagline"
  41. echo
  42. $MkLicense && echo '# See LICENSE.md file for copyright and license details.'
  43. echo ''
  44. echo 'MKIT_DIR=utils/mkit'
  45. #shellcheck disable=SC2016
  46. echo 'include $(MKIT_DIR)/mkit.mk'
  47. ;;
  48. README.md)
  49. echo "$any_name"
  50. tr -c '=\n' '=' <<<"$any_name"
  51. echo ''
  52. if test -n "$Tagline"; then
  53. echo "$Tagline"
  54. else
  55. echo "(Nothing to say about this project.)"
  56. fi
  57. echo ""
  58. echo "See MAINTAINERS.md for instructions how to build and"
  59. echo "maintain this MKit project."
  60. ;;
  61. MAINTAINERS.md)
  62. local heading="$any_name - maintainer instructions"
  63. echo "${heading^^}"
  64. tr -c '=\n' '=' <<<"$heading"
  65. echo ''
  66. echo "<!--"
  67. echo " Note: This file has been auto-generated by MKit"
  68. echo " v$MKIT_VERSION when initializing the project."
  69. echo "-->"
  70. echo ''
  71. echo "This project is using MKit for packaging and versioning"
  72. echo "meta-data; this file describes how to do basic maintenance"
  73. echo "operations."
  74. echo ''
  75. echo "MKit uses GNU Make as an interface, so all operations are"
  76. echo "'make' targets and GNU Make takes care of the dependencies"
  77. echo "between them. For example, to install the project it's enough"
  78. echo "to call 'make install'; GNU Make will call 'make built'"
  79. echo "automatically if needed."
  80. echo ""
  81. echo ""
  82. echo "Variables"
  83. echo "---------"
  84. echo ""
  85. echo " * \`DESTDIR\` - root of the installation destination"
  86. echo " * \`PREFIX\` - deployment prefix (often \`/usr\` or"
  87. echo " \`/usr/local\`)"
  88. echo " * \`MKIT_DRY\` - set to \`true\` to prevent MKit from making"
  89. echo " any changes"
  90. echo " * \`MKIT_DEBUG\` - set to \`true\` to have MKit display"
  91. echo " (lots of) debugging information"
  92. echo ""
  93. echo "See *utils/mkit/include/vars.sh* for full list oof supported"
  94. echo "variables. (You can use \`sfdoc utils/mkit/include/vars.sh\`"
  95. echo "if you have sfdoc installed.)"
  96. echo ""
  97. echo ""
  98. echo "Building and installation"
  99. echo "-------------------------"
  100. echo ""
  101. echo "These operations are allowed on any branch. Assets built from"
  102. echo "development branches will be marked using distinctive version"
  103. echo "number containing timestamp, branch name and commit short-hash."
  104. echo ""
  105. echo " * \`make\` - same as \`make build\`"
  106. echo " * \`make build\` - build project files"
  107. echo " * \`make install\` - install project to \`\$DESTDIR\`"
  108. echo " * \`make uninstall\` - uninstall project from \`\$DESTDIR\`"
  109. echo " * \`make rpmstuff\` - create RPM SPEC file and a source"
  110. echo " tarball"
  111. echo " * \`make debstuff\` - create 'debian' directory and a source"
  112. echo " tarball"
  113. echo " * \`make clean\` - remove any previously built assets".
  114. echo ""
  115. echo ""
  116. echo "Versioning"
  117. echo "----------"
  118. echo ""
  119. echo "These operations are only allowed on *release source branch*:"
  120. echo ""
  121. echo " * \`make vbump\` - bump version and create bump commit"
  122. echo " * \`make release\` - create release tag"
  123. echo ""
  124. echo ""
  125. echo "Recommended workflow"
  126. echo "--------------------"
  127. echo ""
  128. echo ""
  129. echo "### Development and testing ###"
  130. echo ""
  131. echo "Any branch can be used to create any kind of asset. Assets"
  132. echo "built from development branch will be marked using distinctive"
  133. echo "version number in all MKit macros."
  134. echo ""
  135. echo "Development is done in branches as needed, but one branch"
  136. echo "(often called *master*, *main* or *trunk*) is designated as"
  137. echo "**release source** branch. Only maintainer can push into this"
  138. echo "branch and this is where maintainer creates the next release."
  139. echo ""
  140. echo ""
  141. echo "### Versioning and releases ###"
  142. echo ""
  143. echo "After all development branches are merged and project is"
  144. echo "considered ready for release, maintainer will create new"
  145. echo "release. This consists of three steps (only two of them are"
  146. echo "assisted by MKit):"
  147. echo ""
  148. echo " 1. \`make vbump\` - will auto-edit [project:version] in"
  149. echo " mkit.ini and start creating **bump commit**."
  150. echo ""
  151. echo " **Bump commit** is a special commit which consists of:"
  152. echo ""
  153. echo " * Bump of version in mkit.ini"
  154. echo " * commit message providing rudimentary human"
  155. echo " readable summary of changes."
  156. echo ""
  157. echo " \`make vbump\` target will cause bump of the *last*"
  158. echo " version fragment (Z, or PATCH in SemVer). To bump other"
  159. echo " fragments, use \`make vbump_y\` or \`make vbump_x\` (MINOR"
  160. echo " or MAJOR in SemVer, respectively)."
  161. echo ""
  162. echo " MKit will create a template of the message by scanning"
  163. echo " all commits since last release and invoke 'git commit' so"
  164. echo " that maintainer is presented with a window editing the"
  165. echo " commit message."
  166. echo ""
  167. echo " Maintainer is responsible for finishing the commit message"
  168. echo " by:"
  169. echo ""
  170. echo " * Re-wording and merging the items as needed."
  171. echo " * Adding any details, if needed."
  172. echo " * Removing short hashes and file lists added by MKit"
  173. echo " (these are added only to make editing easier)."
  174. echo ""
  175. echo " Once maintainer is happy with *bump commit* message,"
  176. echo " they can exit the editor and move on to next step."
  177. echo ""
  178. echo " 2. \`make release\` - will check if latest commit on current"
  179. echo " branch is a *bump commit*, and if yes, will create"
  180. echo " a corresponding **release tag**."
  181. echo ""
  182. echo " **Release tags** are annotated tags (see *git-tag(1)*)"
  183. echo " formed by version number prefixed by letter \`v\` and are"
  184. echo " used by MKit to calculate version number when building"
  185. echo " assets. Release tags contain the *bump commit* message"
  186. echo " as the annotation."
  187. echo ""
  188. echo " If a *release destination* branch is specified as"
  189. echo " [project:reldst] in mkit.ini, MKit will also update that"
  190. echo " branch so that it points to the same commmit as the"
  191. echo " newly created release tag."
  192. echo ""
  193. echo " 3. Maintainer will push branches and commits to any shared"
  194. echo " remotes as needed."
  195. echo ""
  196. echo " Warning: This is your last chance to fix any mistakes."
  197. echo " git tags are designed to be permanent, \"official\","
  198. echo " write-only objects and they will typically quickly spread"
  199. echo " to other clones. *Don't count on getting rid of release"
  200. echo " tag*."
  201. echo ""
  202. ;;
  203. */mkit.ini|mkit.ini)
  204. echo "[project]"
  205. {
  206. echo "version = $Version"
  207. test -n "$Codename" && echo "codename = $Codename"
  208. test -n "$NiceName" && echo "name = $NiceName"
  209. test -n "$Tagline" && echo "tagline = $Tagline"
  210. test -n "$PackageName" && echo "pkgname = $PackageName"
  211. test -n "$Maintainer" && echo "maintainer = $Maintainer"
  212. test -n "$VcsBrowser" && echo "vcs_browser = $VcsBrowser"
  213. test -n "$RelSrc" && echo "relsrc = $RelSrc"
  214. test -n "$RelDst" && echo "reldst = $RelDst"
  215. } | reformat_section
  216. if updating; then
  217. remake_section dist
  218. remake_section ENV
  219. remake_section roots
  220. remake_section macros
  221. remake_section modes
  222. remake_section files
  223. else
  224. echo ""
  225. echo "[dist]"
  226. {
  227. $MkLicense && echo "tarball = LICENSE.md"
  228. $MkReadme && echo "tarball = MAINTAINERS.md"
  229. $MkMakefile && echo "tarball = Makefile"
  230. $MkReadme && echo "tarball = README.md"
  231. echo "tarball = mkit.ini"
  232. $MkPackaging && echo "tarball = packaging"
  233. echo "tarball = src"
  234. echo "tarball = tests"
  235. echo "tarball = utils"
  236. $MkPackaging && echo "rpmstuff = packaging/template.spec"
  237. $MkPackaging && echo "debstuff = packaging/debian"
  238. } | reformat_section
  239. echo ""
  240. echo "[ENV]"
  241. {
  242. echo " PREFIX = /usr/local"
  243. } | reformat_section
  244. echo ""
  245. echo "[roots]"
  246. {
  247. echo "bin = [ENV:PREFIX]/bin"
  248. echo "doc = [ENV:PREFIX]/share/doc/$PackageName"
  249. } | reformat_section
  250. echo ""
  251. echo "[macros]"
  252. {
  253. echo "__${PackageName^^}_FOO__ = Barr.."
  254. echo " __PROJECT_DESC_MAIN__ = MKIT_STUB_DESCRIPTION - replace this with your project"
  255. echo " __PROJECT_DESC_MAIN__ = MKIT_STUB_DESCRIPTION .. description; this will appear"
  256. echo " __PROJECT_DESC_MAIN__ = MKIT_STUB_DESCRIPTION .. in places like rpm -i"
  257. } | reformat_section
  258. echo ""
  259. echo "[modes]"
  260. {
  261. echo "bin = 755"
  262. echo "doc = 644"
  263. } | reformat_section
  264. echo ""
  265. echo "[files]"
  266. {
  267. echo "bin = src/$PackageName"
  268. $MkLicense && echo "doc = LICENSE.md"
  269. $MkReadme && echo "doc = README.md"
  270. } | reformat_section
  271. fi
  272. echo ""
  273. echo "#mkit version=$MKIT_VERSION"
  274. ;;
  275. packaging/template.spec)
  276. echo 'Name: __MKIT_PROJ_PKGNAME__'
  277. echo 'Version: __MKIT_PROJ_VERSION__'
  278. echo 'Release: 1%{?dist}'
  279. echo 'Summary: __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
  280. test -n "$VcsBrowser" && echo 'URL: __MKIT_PROJ_VCS_BROWSER__'
  281. $MkLicense && echo "License: $License"
  282. echo 'Source0: %{name}-%{version}.tar.gz'
  283. echo 'BuildArch: noarch'
  284. echo 'BuildRequires: make'
  285. echo ''
  286. echo 'Requires: MKIT_STUB_REQUIRES'
  287. echo '%description'
  288. echo '__PROJECT_DESC_MAIN__'
  289. echo ''
  290. echo '%prep'
  291. echo '%setup -q'
  292. echo ''
  293. echo '%build'
  294. echo 'make %{?_smp_mflags} PREFIX=/usr'
  295. echo ''
  296. echo '%install'
  297. echo '%make_install PREFIX=/usr'
  298. echo ''
  299. echo '%files'
  300. echo 'MKIT_STUB_FILELIST'
  301. echo ''
  302. echo '%changelog'
  303. echo ''
  304. echo '# specfile built with MKit __MKIT_MKIT_VERSION__'
  305. echo "# .. based on stub from: $MKIT_VERSION"
  306. ;;
  307. packaging/debian/copyright)
  308. echo ""
  309. ;;
  310. packaging/debian/control)
  311. echo 'Source: __MKIT_PROJ_PKGNAME__'
  312. echo 'Maintainer: __MKIT_PROJ_MAINTAINER__'
  313. test -n "$VcsBrowser" && echo 'Vcs-Browser: __MKIT_PROJ_VCS_BROWSER__'
  314. echo 'Section: misc'
  315. echo 'Priority: extra'
  316. echo 'Standards-Version: 3.9.2'
  317. echo 'Build-Depends:'
  318. echo ' debhelper (>= 9),'
  319. echo ' make,'
  320. echo ''
  321. echo 'Package: __MKIT_PROJ_PKGNAME__'
  322. echo 'Architecture: all'
  323. echo 'Depends: MKIT_STUB_REQUIRES'
  324. echo 'Description: __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
  325. echo ' __PROJECT_DESC_MAIN__'
  326. echo ''
  327. echo '# control file built with MKit __MKIT_MKIT_VERSION__'
  328. echo "# .. based on stub from: $MKIT_VERSION"
  329. ;;
  330. packaging/debian/changelog)
  331. echo '__MKIT_PROJ_PKGNAME__ (__MKIT_PROJ_VERSION__-1) UNRELEASED; urgency=medium'
  332. echo ''
  333. echo ' * Initial release. (Closes: #XXXXXX)'
  334. echo ''
  335. echo " -- __MKIT_PROJ_MAINTAINER__ $(date -R)"
  336. ;;
  337. packaging/debian/compat)
  338. echo 9
  339. ;;
  340. packaging/debian/rules)
  341. echo '#!/usr/bin/make -f'
  342. echo ''
  343. echo '%:'
  344. echo ''
  345. echo ' PREFIX=/usr dh $@'
  346. echo ''
  347. echo 'override_dh_auto_install:'
  348. echo ''
  349. echo ' make install DESTDIR=debian/tmp'
  350. ;;
  351. packaging/debian/source/format)
  352. echo '3.0 (quilt)'
  353. ;;
  354. packaging/debian/install)
  355. echo MKIT_STUB_FILELIST
  356. ;;
  357. src/*.skel)
  358. echo 'echo "my version is: __MKIT_PROJ_VERSION__"'
  359. echo 'echo "And that'"'"'s all, folks!"'
  360. ;;
  361. LICENSE.md)
  362. local url # license URL
  363. url="${MKIT_STUB_LICENSES[$License]}"
  364. curl -sf "$url" \
  365. || die "failed to download license: $url"
  366. ;;
  367. .mkit/autoclean)
  368. ;;
  369. MKIT_STUB_README.md)
  370. echo "FINISHING MKIT CONFIGURATION"
  371. echo "============================"
  372. echo ""
  373. echo "Congratulations, your new project has been configured!"
  374. echo ""
  375. echo "However, the *stub* script is not able to figure out"
  376. echo "everything, so few things still need to be done manually."
  377. echo "This document will guide you throught the rest of the"
  378. echo "process."
  379. echo ""
  380. echo ""
  381. echo "Structure"
  382. echo "---------"
  383. echo ""
  384. echo "First, let's go through the directory structure:"
  385. echo ""
  386. echo " * *src* directory - here is your main place to store"
  387. echo " source files. This includes also documents like user"
  388. echo " manuals---IOW, anything intended to end up on user's"
  389. echo " machine should be uder 'src'."
  390. echo ""
  391. echo " Note that during build time, files named ending with"
  392. echo " '.skel' are subject to macro expansion, see mkit.ini"
  393. echo " section below for details."
  394. echo ""
  395. echo " * *notes* directory - here you shall store notes"
  396. echo " intended for people contributing to your project,"
  397. echo " for instance, guidelines, coding style documents,"
  398. echo " TODOs, ideas, plans..."
  399. echo ""
  400. echo " * *utils* directory - here you shall store utilities"
  401. echo " and scripts that will help you with project maintenance,"
  402. echo " and that, unlike software like compilers or versioning"
  403. echo " systems, can (and should) be embedded inside the"
  404. echo " repository."
  405. echo ""
  406. echo " MKit itself is one nice example. :)"
  407. if $MkPackaging; then
  408. echo ""
  409. echo " * *packaging* directory contains templates that enable"
  410. echo " MKit create raw stuffs used to create DEB or RPM"
  411. echo " packages. Similar to '.skel' files in 'src', all files"
  412. echo " here are automatically considered for macro expansion,"
  413. echo " no matter how they are named (see mkit.ini section"
  414. echo " below)."
  415. echo ""
  416. echo " NOTE: these templates, as well as any packages created by"
  417. echo " them are intended only for experimental, private use and"
  418. echo " testing."
  419. echo ""
  420. echo " Should you have ambition to create 'real' packages for"
  421. echo " OS distribution such as Debian or Fedora (what a great"
  422. echo " idea!), be prepared that you will need to follow their"
  423. echo " guidelines. This will most probably mean huge changes"
  424. echo " to these packages or even changes to your workflow."
  425. echo ""
  426. echo ""
  427. echo "Placeholders"
  428. echo "------------"
  429. echo ""
  430. echo "At places where *stub* script did not have way to get all"
  431. echo "information automatically, it has inserted placeholders."
  432. echo "You will need to go through all of these placeholders and"
  433. echo "replace them with proper data."
  434. echo ""
  435. echo "Please follow instructions:"
  436. echo ""
  437. echo " 1. Look for placeholders starting with \`MKIT_STUB_\`"
  438. echo " prefix by calling this command:"
  439. echo ""
  440. echo " grep -l MKIT_STUB_ -r"
  441. echo ""
  442. echo " 2. Go through each file and locate the placeholder. (You"
  443. echo " will also see placeholders like \`__MKIT_*__\`, you can"
  444. echo " ignore those."
  445. echo ""
  446. echo " 3. Replace placeholder with appropriate information:"
  447. echo ""
  448. echo " * \`MKIT_STUB_REQUIRES\` - Requirements of your"
  449. echo " project."
  450. echo ""
  451. echo " * \`MKIT_STUB_DESCRIPTION\` - Description of your"
  452. echo " project (few sentences to paragraphs)."
  453. echo ""
  454. echo " * \`MKIT_STUB_FILELIST\` - List of full paths to"
  455. echo " your files after installation."
  456. echo ""
  457. echo " Note that in case of debian/install files, PREFIX"
  458. echo " based paths (eg. /usr/bin) in this file should be as"
  459. echo " if PREFIX was /usr."
  460. echo ""
  461. echo " In case of Fedora-based distro, you should make use"
  462. echo " of RPM macros:"
  463. echo ""
  464. echo " https://fedoraproject.org/wiki/Packaging:RPMMacros"
  465. echo ""
  466. echo " Refer to these documents for further details:"
  467. echo ""
  468. echo " http://rpm-guide.readthedocs.io/"
  469. echo " https://www.debian.org/doc/manuals/maint-guide/"
  470. fi
  471. echo ""
  472. echo ""
  473. echo "mkit.ini"
  474. echo "--------"
  475. echo ""
  476. echo "Most sections still need to be reviewed. In order to do"
  477. echo "that, you will need to understand how MKit works:"
  478. echo ""
  479. echo " 1. First, you need to define *roles* your files will play"
  480. echo " when they are installed on user's file systems. These"
  481. echo " roles then imply where and how the files should be"
  482. echo " deployed."
  483. echo ""
  484. echo " Typical example of a role is e.g. 'bin' for commands"
  485. echo " (normally under '/usr/bin' or '/usr/local/bin'), 'doc'"
  486. echo " for documents or 'lib' for libraries."
  487. echo ""
  488. echo " 2. Next, in \`[roots]\` section, you have to set target"
  489. echo " root directory for each role. However, in order to"
  490. echo " enable people to implement local conventions, it is"
  491. echo " considered a good manner to also respect PREFIX"
  492. echo " environment variable. For this reason, most paths"
  493. echo " need to start with \`[ENV:PREFIX]\`."
  494. echo ""
  495. echo " 3. \`[files]\` section is where you assign actual files"
  496. echo " from your repository to their final paths. The format"
  497. echo " is \`ROLE = REPOPATH [RENAMED]\`, where ROLE is file's"
  498. echo " role, REPOPATH is relative path to the file."
  499. echo ""
  500. echo " Final path is then composed by taking path assigned to"
  501. echo " ROLE and appending file's name. However, if you need"
  502. echo " the deployed file to have different name than in the"
  503. echo " codebase, you can specify the other name as RENAMED."
  504. echo ""
  505. echo " Note that you don't need to address every single file"
  506. echo " individually, if in your repo you have a directory with"
  507. echo " 100 files of the same role, you can add just path to the"
  508. echo " directory itself."
  509. echo ""
  510. echo " 4. If some roles require special permissions on your files,"
  511. echo " \`[modes]\` section is your friend. Permissions here"
  512. echo " should be in UNIX octal format."
  513. echo ""
  514. echo " 5. Next, \`[macros]\` section allows you to define own"
  515. echo " placeholders that will be replaced when your scripts are"
  516. echo " built. Each file in 'src' directory that is named with"
  517. echo " '.skel' suffix, and each file from 'packaging' directory"
  518. echo " (no matter its name), can contain one or more of macros"
  519. echo " defined here, plus range of macros automatically defined"
  520. echo " by MKit. During build, these macros are replaced with"
  521. echo " their actual values."
  522. echo ""
  523. echo " 6. Less interesting, but important section is \`[dist]\`,"
  524. echo " which lists files in your codebase that will be added"
  525. echo " to distribution tarball (part of \"stuffs\" mentioned"
  526. echo " above). Listing directory here will include all its"
  527. echo " contents, and normally it's OK to be very inclusive, so"
  528. echo " most of the time this section should be OK."
  529. echo ""
  530. echo " 7. Even less interesting is section \`[ENV]\`. It is"
  531. echo " special in that it provides *default* value for an"
  532. echo " environment variable. You almost never need to touch"
  533. echo " this."
  534. echo ""
  535. echo " 8. Finally, the most interesting section! \`[project]\`,"
  536. echo " provides most general information for your project such"
  537. echo " as name and version."
  538. echo ""
  539. echo " Note that the \`version\` key is another \"special"
  540. echo " snowflake\" -- it is now set to 0.0.0, and you **should"
  541. echo " not need** to change it manually. When you feel you"
  542. echo " a are ready to release next version of your evolving"
  543. echo " project, simply call \`make vbump\` and MKit will take"
  544. echo " care of everything!"
  545. if $MkMakefile; then
  546. echo ""
  547. echo ""
  548. echo "Makefile"
  549. echo "--------"
  550. echo ""
  551. echo "*stub* script also created a Makefile for you, but all"
  552. echo "it really does is include MKit's own mkit.mk, which in turn"
  553. echo "only maps \`make\` targets to actual mkit script calls."
  554. echo "Unless your project already uses GNU Make, you should not"
  555. echo "need to change this file."
  556. fi
  557. if $MkReadme; then
  558. echo ""
  559. echo ""
  560. echo "README.md and MAINTAINERS.md"
  561. echo "----------------------------"
  562. echo ""
  563. echo "Each serious project needs a serious README. Which is why"
  564. echo "*stub* has created a 'stub' of one for you."
  565. echo ""
  566. echo "Furthermore MAINTAINERS.md is created to help maintainers"
  567. echo "do basic MKit operations such as building assets and making"
  568. echo "releases."
  569. fi
  570. echo ""
  571. echo ""
  572. echo "The final touch"
  573. echo "---------------"
  574. echo ""
  575. echo "Once you have reviewed everything, just delete this file!"
  576. ;;
  577. esac >"$tmp"
  578. cat "$tmp" > "$file"
  579. rm "$tmp"
  580. }
  581. known_licenses() {
  582. local key
  583. local first=true
  584. for key in "${!MKIT_STUB_LICENSES[@]}"; do
  585. $first && echo "$key" && continue
  586. echo ", $key"
  587. done
  588. }
  589. usage() {
  590. {
  591. echo "Usage:"
  592. echo " stub [options] new PKGNAME"
  593. echo " stub [options] update"
  594. echo " stub -L"
  595. echo ""
  596. echo "Options:"
  597. echo ""
  598. echo " -c CODENAME your project codename"
  599. echo " -t TAGLINE your project tagline"
  600. echo " -b RELSRC pre-release branch"
  601. echo " -B RELDST post-release branch"
  602. echo " -n NICENAME your project's 'nice' name"
  603. echo " -l LICENSE your options's license (see -L)"
  604. echo " -m MAINT project maintainer's name and e-mail"
  605. echo " -v URL URL to public code browser"
  606. echo " -V VERSION initial version (default: 0.0.0)"
  607. echo " -a enable autoclean ('make clean' after"
  608. echo " each 'make install')"
  609. echo " -g make git commits before and after"
  610. echo " (implies -y)"
  611. echo " -y don't ask, just do it"
  612. echo " -R skip creating README.md"
  613. echo " -M skip creating Makefile"
  614. echo " -P skip creating packaging templates"
  615. echo " -L list known licenses and exit"
  616. echo ""
  617. echo "PKGNAME should be packaging-friendly name, ie. consist"
  618. echo "only of small letters, numbers, underscore and dash."
  619. echo "For your 'real' name, use NICENAME, which can be any"
  620. echo "string."
  621. } >&2
  622. exit 2
  623. }
  624. confirm() {
  625. local response # user's response to our warning
  626. $Force && return 0
  627. {
  628. echo "Warning: This operation can be destructive for your"
  629. echo "current codebase. At least following files will be"
  630. echo "created or overwritten:"
  631. echo ""
  632. $MkPackaging && echo " * 'packaging' directory (pass -P to avoid)"
  633. $MkMakefile && echo " * 'Makefile' (pass -M to avoid)"
  634. $MkReadme && echo " * 'README.md' (pass -R to avoid)"
  635. $MkLicense && echo " * 'LICENSE.md' (omit -l to avoid)"
  636. echo " * 'mkit.ini'"
  637. echo ""
  638. read -p "Type 'yes' to proceed: " -r response
  639. } >&2
  640. test "$response" == "yes" && return 0
  641. warn "Aborting."
  642. return 1
  643. }
  644. mkcommit_backup() {
  645. git ls-files --others \
  646. | grep -qv -e '^utils/mkit$' -e '^utils/mkit/' \
  647. || { warn "nothing to back up"; return 0; }
  648. git add . || return
  649. git rm -r --cached utils/mkit || return
  650. git commit -m "WIP [mkit/stub] backup" || return
  651. }
  652. mkcommit_mkit_code() {
  653. git ls-files --others \
  654. | grep -q -e '^utils/mkit$' -e '^utils/mkit/' \
  655. || return 0
  656. git add utils/mkit || return
  657. git commit -m "WIP [mkit/stub] Add MKit version v$MKIT_VERSION" || return
  658. }
  659. mkcommit_mkit_conf() {
  660. local msg # commit message (the important art
  661. git add . || return
  662. case $Action in
  663. new) msg="Add MKit configuration stub" ;;
  664. update) msg="Update MKit configuration" ;;
  665. esac
  666. git commit -m "WIP [mkit/stub] $msg" || return
  667. }
  668. deploy_packaging() {
  669. rm -rf packaging
  670. deploy packaging/template.spec
  671. deploy packaging/debian/copyright
  672. deploy packaging/debian/control
  673. deploy packaging/debian/changelog
  674. deploy packaging/debian/compat
  675. deploy packaging/debian/install
  676. deploy packaging/debian/rules
  677. deploy packaging/debian/source/format
  678. }
  679. init_from_existing() {
  680. #
  681. # Initialize variables from old mkit.ini
  682. #
  683. test -f "$MKIT_INI" \
  684. || die "mkit.ini not found; aborting update: $MKIT_INI"
  685. user_gave Codename || Codename=$(ini_raw1v project:codename)
  686. user_gave License || License=$(ini_raw1v project:license)
  687. user_gave Maintainer || Maintainer=$(ini_raw1v project:maintainer)
  688. user_gave NiceName || NiceName=$(ini_raw1v project:name)
  689. user_gave PackageName || PackageName=$(ini_raw1v project:pkgname)
  690. user_gave RelDst || RelDst=$(ini_raw1v project:reldst)
  691. user_gave RelSrc || RelSrc=$(ini_raw1v project:relsrc)
  692. user_gave Tagline || Tagline=$(ini_raw1v project:tagline)
  693. user_gave VcsBrowser || VcsBrowser=$(ini_raw1v project:vcs_browser)
  694. user_gave Version || Version=$(ini_raw1v project:version)
  695. }
  696. ini_raw1v() {
  697. #
  698. # Read raw scalar from mkit.ini
  699. #
  700. local path=$1
  701. MKIT_INI_EXPAND=0 ini 1value "$path"
  702. }
  703. user_gave() {
  704. #
  705. # True if user gave value to variable $1
  706. #
  707. local var=$1 # name of the variable
  708. { test "${UserGave[$var]}" == 1; } 2>/dev/null
  709. }
  710. updating() {
  711. #
  712. # Are we updating?
  713. #
  714. test "$Action" == update
  715. }
  716. remake_section() {
  717. #
  718. # Re-compose mkit.ini section $1
  719. #
  720. local section=$1
  721. local key
  722. local value
  723. ini lskeys "$section" | grep -q . \
  724. || return 1
  725. echo ""
  726. echo "[$section]"
  727. ini lskeys "$section" \
  728. | while read -r key; do
  729. MKIT_INI_EXPAND=0 ini values "$section:$key" \
  730. | while read -r value; do
  731. echo "$key = $value"
  732. done
  733. done \
  734. | reformat_section
  735. }
  736. reformat_section() {
  737. #
  738. # Re-format "k = v" on stdin as "nice" ini section
  739. #
  740. local key
  741. local eq
  742. local value
  743. while read -r key eq value; do
  744. test "$eq" == "=" || {
  745. warn "ignoring malformed ini line: $key $eq $value"
  746. continue
  747. }
  748. echo "$key = $value"
  749. done \
  750. | sed 's/ *= */=/; s/^ *//; s/ *$//' \
  751. | column -t -s= -o' = ' \
  752. | sed 's/^/ /'
  753. }
  754. main() {
  755. local NiceName # human-readable project name
  756. local PackageName # machine-safe project (package) name
  757. local RelSrc # pre-release branch
  758. local RelDst # post-release branch
  759. local Codename # release codename
  760. local Tagline # project tagline
  761. local Maintainer # project maintainer (Name + e-mail)
  762. local VcsBrowser # VCS browser (eg. GitHub URL)
  763. local Version=0.0.0 # project version
  764. local AutoClean=false # touch .mkit/autoclean?
  765. local MkCommits=false # create pre/post git commits?
  766. local Force=false # go without asking?
  767. local MkReadme=true # create README.md?
  768. local MkMakefile=true # create Makefile?
  769. local MkPackaging=true # create packaging templates?
  770. local MkLicense=false # create LICENSE.md file
  771. local Action # 'update' to respect existing, 'new' to force
  772. # rewrite incl. MKIT_STUB_* placeholders
  773. declare -A UserGave
  774. while true; do case $1 in
  775. -n) NiceName=$2; UserGave[NiceName]=1; shift 2 || usage ;;
  776. -b) RelSrc=$2; UserGave[RelSrc]=1; shift 2 || usage ;;
  777. -B) RelDst=$2; UserGave[RelDst]=1; shift 2 || usage ;;
  778. -c) Codename=$2; UserGave[Codename]=1; shift 2 || usage ;;
  779. -t) Tagline=$2; UserGave[Tagline]=1; shift 2 || usage ;;
  780. -l) License=$2; UserGave[License]=1; shift 2 || usage ;;
  781. -m) Maintainer=$2; UserGave[Maintainer]=1; shift 2 || usage ;;
  782. -v) VcsBrowser=$2; UserGave[VcsBrowser]=1; shift 2 || usage ;;
  783. -V) Version=$2; UserGave[Version]=1; shift 2 || usage ;;
  784. -M) MkMakefile=false; shift ;;
  785. -R) MkReadme=false; shift ;;
  786. -a) AutoClean=true; shift ;;
  787. -y) Force=true; shift ;;
  788. -g) MkCommits=true; shift ;;
  789. -P) MkPackaging=false; shift ;;
  790. -L) known_licenses | tr , '\n'; exit 0 ;;
  791. -*) usage ;;
  792. *) break ;;
  793. esac done
  794. Action=$1; PackageName=$2
  795. case $Action:$PackageName in
  796. new:) usage ;;
  797. new:*) : ;;
  798. update:) : ;;
  799. update:*) usage ;;
  800. *) usage ;;
  801. esac
  802. updating && init_from_existing
  803. if test -n "$License"; then
  804. known_licenses | grep -qxFe "$License" \
  805. || die "unknown license (use -L to get list): $License"
  806. MkLicense=true
  807. fi
  808. if $MkCommits; then
  809. mkcommit_backup || die "failed creating backup commit"
  810. Force=true
  811. fi
  812. confirm || return 1
  813. deploy "$MKIT_INI"
  814. deploy src/"$PackageName".skel
  815. $MkMakefile && deploy Makefile
  816. $MkReadme && deploy README.md
  817. $MkReadme && deploy MAINTAINERS.md
  818. $MkLicense && deploy LICENSE.md
  819. $AutoClean && deploy .mkit/autoclean
  820. $MkPackaging && deploy_packaging
  821. if $MkCommits; then
  822. mkcommit_mkit_code || die "failed creating post-commit"
  823. mkcommit_mkit_conf || die "failed creating post-commit"
  824. fi
  825. deploy MKIT_STUB_README.md
  826. warn "Configuration stub built, follow instructions in"
  827. warn "MKIT_STUB_README.md to finish configuration."
  828. return 0
  829. }
  830. main "$@"