123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- #!/bin/bash
- # mkit - simple install helper
- # See LICENSE file for copyright and license details.
-
- init_core() {
- #
- # Load core modules (or die)
- #
- #shellcheck disable=SC1090
- . "$MKIT_DIR/include/mkit.sh" \
- && . "$MKIT_DIR/include/vars.sh" \
- && return 0
- echo "failed to load core; check if MKIT_DIR is set properly: $MKIT_DIR" >&2
- exit 9
- }
-
- #
- # Path to MKit dir (where 'include' is)
- #
- MKIT_DIR=${MKIT_DIR:-$(dirname "$0")}
-
- init_core
-
- declare -A MKIT_INIT_LICENSES
- MKIT_INIT_LICENSES[GPLv1]="http://www.gnu.org/licenses/old-licenses/gpl-1.0.md"
- MKIT_INIT_LICENSES[GPLv2]="http://www.gnu.org/licenses/old-licenses/gpl-2.0.md"
- MKIT_INIT_LICENSES[GPLv3]="http://www.gnu.org/licenses/gpl-3.0.md"
- MKIT_INIT_LICENSES[LGPLv2]="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.md"
- MKIT_INIT_LICENSES[LGPLv3]="http://www.gnu.org/licenses/lgpl-3.0.md"
- MKIT_INIT_LICENSES[AGPLv3]="http://www.gnu.org/licenses/agpl-3.0.md"
- MKIT_INIT_LICENSES[FDLv1.3]="http://www.gnu.org/licenses/fdl-1.3.md"
- MKIT_INIT_LICENSES[FDLv1.2]="http://www.gnu.org/licenses/old-licenses/fdl-1.2.md"
- MKIT_INIT_LICENSES[FDLv1.1]="http://www.gnu.org/licenses/old-licenses/fdl-1.1.md"
-
-
- deploy() {
- local file=$1 # which known file?
- local any_name=${NiceName:-$PackageName}
- mkdir -p "$(dirname "$file")"
- case $file in
-
- Makefile)
- echo -n "# $any_name"
- test -n "$Tagline" && echo -n " - $Tagline"
- echo
- echo '# See LICENSE.md file for copyright and license details.'
- echo ''
- echo 'MKIT_DIR=utils/mkit'
- #shellcheck disable=SC2016
- echo 'include $(MKIT_DIR)/mkit.mk'
- ;;
-
- README.md)
- echo "$any_name"
- tr -c '=\n' '=' <<<"$any_name"
- echo ''
- echo ''
- if test -n "$Tagline"; then
- echo "$Tagline"
- else
- echo "(Nothing to say about this project.)"
- fi
- ;;
-
- mkit.ini)
- echo "[project]"
- echo " version = 0.0.0"
- test -n "$Codename" && echo " codename = $Codename"
- test -n "$NiceName" && echo " name = $NiceName"
- test -n "$Tagline" && echo " tagline = $Tagline"
- test -n "$PackageName" && echo " pkgname = $PackageName"
- test -n "$Maintainer" && echo " maintainer = $Maintainer"
- test -n "$VcsBrowser" && echo " vcs_browser = $VcsBrowser"
- test -n "$RelSrc" && echo " relsrc = $RelSrc"
- test -n "$RelDst" && echo " reldst = $RelDst"
- echo ""
- echo "[dist]"
- echo " tarball = LICENSE.md"
- $MkMakefile && echo " tarball = Makefile"
- $MkReadme && echo " tarball = README.md"
- echo " tarball = mkit.ini"
- $MkPackaging && echo " tarball = packaging"
- echo " tarball = src"
- echo " tarball = tests"
- echo " tarball = utils"
- $MkPackaging && echo " rpmstuff = packaging/template.spec"
- $MkPackaging && echo " debstuff = packaging/debian"
- echo ""
- echo "[ENV]"
- echo " PREFIX = /usr/local"
- echo ""
- echo "[roots]"
- echo " bin = [ENV:PREFIX]/bin"
- echo " doc = [ENV:PREFIX]/share/doc/$PackageName"
- echo ""
- echo "[tokens]"
- echo " __BIN_DIR__ = [roots:bin]"
- echo ""
- echo "[modes]"
- echo " bin = 755"
- echo " doc = 644"
- echo ""
- echo "[files]"
- echo " bin = src/$PackageName"
- $MkLicense && echo " doc = LICENSE.md"
- $MkReadme && echo " doc = README.md"
- echo ""
- echo "#mkit version=$MKIT_VERSION"
- ;;
-
- packaging/template.spec)
- echo 'Name: __MKIT_PROJ_PKGNAME__'
- echo 'Version: __MKIT_PROJ_VERSION__'
- echo 'Release: 1%{?dist}'
- echo 'Summary: __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
- echo ''
- $MkLicense && echo "License: $License"
- echo 'Source0: %{name}-%{version}.tar.gz'
- echo ''
- echo 'BuildArch: noarch'
- echo 'BuildRequires: coreutils git'
- echo 'Requires: MKIT_NEWSTUB_REQUIRES'
- echo ''
- echo '%description'
- echo 'MKIT_NEWSTUB_DESCRIPTION'
- echo ''
- echo '%prep'
- echo '%setup -q'
- echo ''
- echo '%build'
- echo 'make %{?_smp_mflags}'
- echo ''
- echo '%install'
- echo '%make_install'
- echo ''
- echo '%files'
- echo 'MKIT_NEWSTUB_FILELIST'
- echo ''
- echo '%changelog'
- echo ''
- echo '# specfile built with MKit __MKIT_SELF_VERSION__'
- ;;
-
- packaging/debian/copyright)
- echo ""
- ;;
-
- packaging/debian/control)
- echo 'Source: __MKIT_PROJ_PKGNAME__'
- echo 'Maintainer: __MKIT_PROJ_MAINTAINER__'
- test -n "$VcsBrowser" && echo 'Vcs-Browser: __MKIT_PROJ_VCS_BROWSER__'
- echo 'Section: misc'
- echo 'Priority: extra'
- echo 'Standards-Version: 3.9.2'
- echo 'Build-Depends: debhelper (>= 9)'
- echo ''
- echo 'Package: __MKIT_PROJ_PKGNAME__'
- echo 'Architecture: all'
- echo 'Depends: MKIT_NEWSTUB_REQUIRES'
- echo 'Description: __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
- echo ' MKIT_NEWSTUB_DESCRIPTION'
- echo ''
- echo '# control file built with MKit __MKIT_SELF_VERSION__'
- ;;
-
- packaging/debian/changelog)
- echo '__MKIT_PROJ_PKGNAME__ (__MKIT_PROJ_VERSION__-1) UNRELEASED; urgency=medium'
- echo ''
- echo ' * Initial release. (Closes: #XXXXXX)'
- echo ''
- echo " -- __MKIT_PROJ_MAINTAINER__ $(date -R)"
- ;;
-
- packaging/debian/compat)
- echo 9
- ;;
-
- packaging/debian/rules)
- echo '#!/usr/bin/make -f'
- echo ''
- echo '%:'
- echo ''
- echo ' dh $@'
- echo ''
- echo 'override_dh_auto_install:'
- echo ''
- echo ' make install DESTDIR=debian/tmp'
- echo ''
- echo 'override_dh_usrlocal:'
- echo ''
- echo ' @true'
- ;;
-
- packaging/debian/source/format)
- echo '3.0 (quilt)'
- ;;
-
- packaging/debian/*.install)
- echo MKIT_NEWSTUB_FILELIST
- ;;
-
- src/*.skel)
- echo 'echo "my version is: __MKIT_PROJ_VERSION__"'
- echo 'echo "And that'"'"'s all, folks!"'
- ;;
-
- LICENSE.md)
- local url # license URL
- url="${MKIT_INIT_LICENSES[$License]}"
- curl -sf "$url" \
- || die "failed to download license: $url"
- ;;
-
- .mkit/autoclean)
- ;;
-
- MKIT_NEWSTUB_README.md)
- echo "FINISHING MKIT CONFIGURATION"
- echo "============================"
- echo ""
- echo "Congratulations, your new project has been configured!"
- echo ""
- echo "However, the *newstub* script is not able to figure out"
- echo "everything, so few things still need to be done manually."
- echo "This document will guide you throught the rest of the"
- echo "process."
-
- echo ""
- echo ""
- echo "Structure"
- echo "---------"
- echo ""
- echo "First, let's go through the directory structure:"
- echo ""
- echo " * *src* directory - here is your main place to store"
- echo " source files. This includes also documents like user"
- echo " manuals---IOW, anything intended to end up on user's"
- echo " machine should be uder 'src'."
- echo ""
- echo " Note that during build time, files named ending with"
- echo " '.skel' are subject to token expansion, see mkit.ini"
- echo " section below for details."
- echo ""
- echo " * *notes* directory - here you shall store notes"
- echo " intended for people contributing to your project,"
- echo " for instance, guidelines, coding style documents,"
- echo " TODOs, ideas, plans..."
- echo ""
- echo " * *utils* directory - here you shall store utilities"
- echo " and scripts that will help you with project maintenance,"
- echo " and that, unlike software like compilers or versioning"
- echo " systems, can (and should) be embedded inside the"
- echo " repository."
- echo ""
- echo " MKit itself is one nice example. :)"
-
- if $MkPackaging; then
- echo ""
- echo " * *packaging* directory contains templates that enable"
- echo " MKit create raw stuffs used to create DEB or RPM"
- echo " packages. Similar to '.skel' files in 'src', all files"
- echo " here are automatically considered for token expansion,"
- echo " no matter how they are named (see mkit.ini section"
- echo " below)."
- echo ""
- echo " NOTE: these templates, as well as any packages created by"
- echo " them are intended only for experimental, private use and"
- echo " testing."
- echo ""
- echo " Should you have ambition to create 'real' packages for"
- echo " OS distribution such as Debian or Fedora (what a great"
- echo " idea!), be prepared that you will need to follow their"
- echo " guidelines. This will most probably mean huge changes"
- echo " to these packages or even changes to your workflow."
-
- echo ""
- echo ""
- echo "Placeholders"
- echo "------------"
- echo ""
- echo "At places where *newstub* script did not have way to get all"
- echo "information automatically, it has inserted placeholders."
- echo "You will need to go through all of these placeholders and"
- echo "replace them with proper data."
- echo ""
- echo "Please follow instructions:"
- echo ""
- echo " 1. Look for placeholders starting with \`MKIT_NEWSTUB_\`"
- echo " prefix by calling this command:"
- echo ""
- echo " grep -lw MKIT_NEWSTUB_ -r"
- echo ""
- echo " 2. Go through each file and locate the placeholder. (You"
- echo " will also see placeholders like \`__MKIT_*__\`, you can"
- echo " ignore those."
- echo ""
- echo " 3. Replace placeholder with appropriate information:"
- echo ""
- echo " * \`MKIT_NEWSTUB_REQUIRES\` - Requirements of your"
- echo " project."
- echo ""
- echo " * \`MKIT_NEWSTUB_DESCRIPTION\` - Description of your"
- echo " project (few sentences to paragraphs)."
- echo ""
- echo " * \`MKIT_NEWSTUB_FILELIST\` - List of full paths to"
- echo " your files after installation."
- echo ""
- echo " Refer to these documents for further details:"
- echo ""
- echo " http://rpm-guide.readthedocs.io/"
- echo " https://www.debian.org/doc/manuals/maint-guide/"
- fi
-
- echo ""
- echo ""
- echo "mkit.ini"
- echo "--------"
- echo ""
- echo "Most sections still need to be reviewed. In order to do"
- echo "that, you will need to understand how MKit works:"
- echo ""
- echo " 1. First, you need to define *roles* your files will play"
- echo " when they are installed on user's file systems. These"
- echo " roles then imply where and how the files should be"
- echo " deployed."
- echo ""
- echo " Typical example of a role is e.g. 'bin' for commands"
- echo " (normally under '/usr/bin' or '/usr/local/bin'), 'doc'"
- echo " for documents or 'lib' for libraries."
-
- echo ""
- echo " 2. Next, in \`[roots]\` section, you have to set target"
- echo " root directory for each role. However, in order to"
- echo " enable people to implement local conventions, it is"
- echo " considered a good manner to also respect PREFIX"
- echo " environment variable. For this reason, most paths"
- echo " need to start with \`[ENV:PREFIX]\`."
- echo ""
-
- echo " 3. \`[files]\` section is where you assign actual files"
- echo " from your repository to their final paths. The format"
- echo " is \`ROLE = REPOPATH [RENAMED]\`, where ROLE is file's"
- echo " role, REPOPATH is relative path to the file."
- echo ""
- echo " Final path is then composed by taking path assigned to"
- echo " ROLE and appending file's name. However, if you need"
- echo " the deployed file to have different name than in the"
- echo " codebase, you can specify the other name as RENAMED."
- echo ""
- echo " Note that you don't need to address every single file"
- echo " individually, if in your repo you have a directory with"
- echo " 100 files of the same role, you can add just path to the"
- echo " directory itself."
-
- echo ""
- echo " 4. If some roles require special permissions on your files,"
- echo " \`[modes]\` section is your friend. Permissions here"
- echo " should be in UNIX octal format."
-
- echo ""
- echo " 5. Next, \`[tokens]\` section allows you to define own"
- echo " placeholders that will be replaced when your scripts are"
- echo " built. Each file in 'src' directory that is named with"
- echo " '.skel' suffix, and each file from 'packaging' directory"
- echo " (no matter its name), can contain one or more of tokens"
- echo " defined here, plus range of tokens automatically defined"
- echo " by MKit. During build, these tokens are replaced with"
- echo " their actual values."
-
- echo ""
- echo " 6. Less interesting, but important section is \`[dist]\`,"
- echo " which lists files in your codebase that will be added"
- echo " to distribution tarball (part of \"stuffs\" mentioned"
- echo " above). Listing directory here will include all its"
- echo " contents, and normally it's OK to be very inclusive, so"
- echo " most of the time this section should be OK."
-
- echo ""
- echo " 7. Even less interesting is section \`[ENV]\`. It is"
- echo " special in that it provides *default* value for an"
- echo " environment variable. You almost never need to touch"
- echo " this."
- echo ""
-
- echo " 8. Finally, the most interesting section! \`[project]\`,"
- echo " provides most general information for your project such"
- echo " as name and version."
- echo ""
- echo " Note that the \`version\` key is another \"special"
- echo " snowflake\" -- it is now set to 0.0.0, and you **should"
- echo " not need** to change it manually. When you feel you"
- echo " a are ready to release next version of your evolving"
- echo " project, simply call \`make vbump\` and MKit will take"
- echo " care of everything!"
-
- if $MkMakefile; then
- echo ""
- echo ""
- echo "Makefile"
- echo "--------"
- echo ""
- echo "*newstub* script also created a Makefile for you, but all"
- echo "it really does is include MKit's own mkit.mk, which in turn"
- echo "only maps \`make\` targets to actual mkit script calls."
- echo "Unless your project already uses GNU Make, you should not"
- echo "need to change this file."
- fi
-
- if $MkReadme; then
- echo ""
- echo ""
- echo "README.md"
- echo "---------"
- echo ""
- echo "Each serious project needs a serious README. Which is why"
- echo "*newstub* has created a 'stub' of one for you."
- fi
-
- echo ""
- echo ""
- echo "The final touch"
- echo "---------------"
- echo ""
- echo "Once you have reviewed everything, just delete this file!"
- ;;
-
- esac >"$file"
- }
-
- known_licenses() {
- local key
- local first=true
- for key in "${!MKIT_INIT_LICENSES[@]}"; do
- $first && echo "$key" && continue
- echo ", $key"
- done
- }
-
- usage() {
- {
- echo "Usage:"
- echo " newstub [options] NAME"
- echo " newstub -L"
- echo ""
- echo "Options:"
- echo ""
- echo " -c CODENAME your project codename"
- echo " -t TAGLINE your project tagline"
- echo " -b RELSRC pre-release branch"
- echo " -B RELDST post-release branch"
- echo " -n NICENAME your project's 'nice' name"
- echo " -l LICENSE your options's license (see -L)"
- echo " -m MAINT project maintainer's name and e-mail"
- echo " -v URL URL to public code browser"
- echo " -a enable autoclean ('make clean' after"
- echo " each 'make install')"
- echo " -g make git commits before and adter"
- echo " (implies -y)"
- echo " -y don't ask, just do it"
- echo " -R skip creating README.md"
- echo " -M skip creating Makefile"
- echo " -P skip creating packaging templates"
- echo " -L list know licenses and exit"
- echo ""
- echo "NAME should be packaging-friendly name, ie. consist"
- echo "only of small letters, numbers, underscore and dash."
- echo "For your 'real' name, use NICENAME, which can be any"
- echo "string."
- } >&2
- exit 2
- }
-
- confirm() {
- local response # user's response to our warning
- $Force && return 0
- {
- echo "Warning: This operation can be destructive for your"
- echo "current codebase. At least following files will be"
- echo "created or overwritten:"
- echo ""
- $MkPackaging && echo " * 'packaging' directory (pass -P to avoid)"
- $MkMakefile && echo " * 'Makefile' (pass -M to avoid)"
- $MkReadme && echo " * 'README.md' (pass -R to avoid)"
- $MkLicense && echo " * 'LICENSE.md' (omit -l to avoid)"
- echo " * 'mkit.ini'"
- echo ""
- read -p "Type 'yes' to proceed: " -r response
- } >&2
- test "$response" == "yes" && return 0
- warn "Aborting."
- return 1
- }
-
- mkcommit_backup() {
- git ls-files --others \
- | grep -qv -e '^utils/mkit$' -e '^utils/mkit/' \
- || { warn "nothing to back up"; return 0; }
- git add . || return
- git rm -r --cached utils/mkit || return
- git commit -m "WIP [mkit/newstub] backup" || return
- }
-
- mkcommit_mkit_code() {
- git ls-files --others \
- | grep -q -e '^utils/mkit$' -e '^utils/mkit/' \
- || return 0
- git add utils/mkit || return
- git commit -m "WIP [mkit/newstub] Add MKit version v$MKIT_VERSION" || return
- }
-
- mkcommit_mkit_conf() {
- git add . || return
- git commit -m "WIP [mkit/newstub] Add MKit configuration stub" || return
- }
-
- deploy_packaging() {
- rm -rf packaging
- deploy packaging/template.spec
- deploy packaging/debian/copyright
- deploy packaging/debian/control
- deploy packaging/debian/changelog
- deploy packaging/debian/compat
- deploy packaging/debian/rules
- deploy packaging/debian/source/format
- deploy packaging/debian/"$PackageName".install
- deploy packaging/template.spec
- }
-
- main() {
- local NiceName # human-readable project name
- local PackageName # machine-safe project (package) name
- local RelSrc # pre-release branch
- local RelDst # post-release branch
- local Codename # release codename
- local Tagline # project tagline
- local Maintainer # project maintainer (Name + e-mail)
- local VcsBrowser # VCS browser (eg. GitHub URL)
- local AutoClean=false # touch .mkit/autoclean?
- local MkCommits=false # create pre/post git commits?
- local Force=false # go without asking?
- local MkReadme=true # create README.md?
- local MkMakefile=true # create Makefile?
- local MkPackaging=true # create packaging templates?
- local MkLicense=false # create LICENSE.md file
- while true; do case $1 in
- -n) NiceName=$2; shift 2 || usage ;;
- -b) RelSrc=$2; shift 2 || usage ;;
- -B) RelDst=$2; shift 2 || usage ;;
- -c) Codename=$2; shift 2 || usage ;;
- -t) Tagline=$2; shift 2 || usage ;;
- -l) License=$2; shift 2 || usage ;;
- -m) Maintainer=$2; shift 2 || usage ;;
- -v) VcsBrowser=$2; shift 2 || usage ;;
- -M) MkMakefile=false; shift ;;
- -R) MkReadme=false; shift ;;
- -a) AutoClean=true; shift ;;
- -y) Force=true; shift ;;
- -g) MkCommits=true; shift ;;
- -P) MkPackaging=false; shift ;;
- -L) known_licenses | tr , '\n'; exit 0 ;;
- -*) usage ;;
- *) break ;;
- esac done
- PackageName="$1"
- test -n "$PackageName" || usage
- if test -n "$License"; then
- known_licenses | grep -qxF "$License" \
- || die "unknown license (use -L to get list): $License"
- MkLicense=true
- fi
- if $MkCommits; then
- mkcommit_backup || die "failed creating backup commit"
- Force=true
- fi
- confirm || return 1
- deploy mkit.ini
- deploy src/"$PackageName".skel
- $MkMakefile && deploy Makefile
- $MkReadme && deploy README.md
- $MkLicense && deploy LICENSE.md
- $AutoClean && deploy .mkit/autoclean
- $MkPackaging && deploy_packaging
- if $MkCommits; then
- mkcommit_mkit_code || die "failed creating post-commit"
- mkcommit_mkit_conf || die "failed creating post-commit"
- fi
- deploy MKIT_NEWSTUB_README.md
- warn "Configuration stub built, follow instructions in"
- warn "MKIT_NEWSTUB_README.md to finish configuration."
- return 0
- }
-
- main "$@"
|