On Tue, 2020-04-28 at 17:36 -0400, Jeremy Cline wrote: > Recently I needed to deploy Patchwork and I noticed it was missing a > setup.py. This is a first draft at adding one and making Patchwork easy > to install with pip. > > To do this, static files and templates are moved within the Python > package. "htdocs" is renamed to "static" which is the default location > Django searches for static files. The two templates directories have > been merged - I'm not sure why there are two so this perhaps breaks > something I'm not aware of. > > With this change you should be able to do something like: > > $ python3 setup.py sdist > $ python3 -m venv ~/.virtualenvs/pw > $ source ~/.virtualenvs/pw/bin/activate > $ pip install dist/patchwork-3.0.0a1.tar.gz > $ DJANGO_SETTINGS_MODULE=patchwork.settings.dev PW_TEST_DB_TYPE=sqlite \ > django-admin migrate > $ DJANGO_SETTINGS_MODULE=patchwork.settings.dev PW_TEST_DB_TYPE=sqlite \ > django-admin runserver > > I poked around the web UI and everything seems to work as expected, but > it's quite likely I've missed something. This change would obviously > also require updating the installation documentation, but before I go > any further I'd love some feedback on this. Is this something people are > interested in? > > My motivation for this is that I've got a little Django app that runs > alongside Patchwork and would prefer it to be a simple "pip install" to > get everything set up.
Sorry for the delay getting to this /o\ I've considered doing this myself for some time and the main reason I hadn't was because Patchwork isn't really packaged as a library or something reusable - it's an application (in the packaging sense of the word [1]). As such, I'm not sure how much sense there would be in publishing Patchwork to PyPI and, for me at least, a setup.py file only real makes sense in that context [2]. With that said, you've suggested that this is beneficial for you at least. Could you go into a little more on this? I'd have suspected an Ansible playbook or production Docker container to be far more useful because they'd include things like nginx/Apache setup, etc. Is that not the case? Cheers, Stephen [1] https://caremad.io/posts/2013/07/setup-vs-requirement/ [2] Yes, you have distutils commands, but there are almost always alternatives you can use for this. > Signed-off-by: Jeremy Cline <jcl...@redhat.com> > --- > MANIFEST.in | 7 ++ > htdocs/js/jquery-1.10.1.min.js | 1 - > htdocs/js/jquery.checkboxes-1.0.6.min.js | 1 - > htdocs/js/jquery.stickytableheaders.min.js | 1 - > htdocs/js/jquery.tablednd.js | 1 - > patchwork/settings/base.py | 4 +- > {htdocs => patchwork/static}/README.rst | 0 > .../static}/css/bootstrap.min.css | 0 > .../static}/css/selectize.bootstrap3.css | 0 > {htdocs => patchwork/static}/css/style.css | 0 > .../fonts/glyphicons-halflings-regular.eot | Bin > .../fonts/glyphicons-halflings-regular.svg | 0 > .../fonts/glyphicons-halflings-regular.ttf | Bin > .../fonts/glyphicons-halflings-regular.woff | Bin > .../static}/js/bootstrap.min.js | 0 > {htdocs => patchwork/static}/js/bundle.js | 0 > .../static}/js/clipboard.min.js | 0 > patchwork/static/js/jquery-1.10.1.min.js | 1 + > .../static/js/jquery.checkboxes-1.0.6.min.js | 1 + > .../js/jquery.stickytableheaders.min.js | 1 + > patchwork/static/js/jquery.tablednd.js | 1 + > .../static}/js/selectize.min.js | 0 > {templates => patchwork/templates}/404.html | 0 > {templates => patchwork/templates}/base.html | 0 > .../registration/password_change_done.html | 0 > .../registration/password_change_form.html | 0 > .../registration/password_reset_complete.html | 0 > .../registration/password_reset_confirm.html | 0 > .../registration/password_reset_done.html | 0 > .../registration/password_reset_email.html | 0 > .../registration/password_reset_form.html | 0 > requirements-test.txt | 2 +- > setup.py | 69 ++++++++++++++++++ > 33 files changed, 83 insertions(+), 7 deletions(-) > create mode 100644 MANIFEST.in > delete mode 120000 htdocs/js/jquery-1.10.1.min.js > delete mode 120000 htdocs/js/jquery.checkboxes-1.0.6.min.js > delete mode 120000 htdocs/js/jquery.stickytableheaders.min.js > delete mode 120000 htdocs/js/jquery.tablednd.js > rename {htdocs => patchwork/static}/README.rst (100%) > rename {htdocs => patchwork/static}/css/bootstrap.min.css (100%) > rename {htdocs => patchwork/static}/css/selectize.bootstrap3.css (100%) > rename {htdocs => patchwork/static}/css/style.css (100%) > rename {htdocs => patchwork/static}/fonts/glyphicons-halflings-regular.eot > (100%) > rename {htdocs => patchwork/static}/fonts/glyphicons-halflings-regular.svg > (100%) > rename {htdocs => patchwork/static}/fonts/glyphicons-halflings-regular.ttf > (100%) > rename {htdocs => patchwork/static}/fonts/glyphicons-halflings-regular.woff > (100%) > rename {htdocs => patchwork/static}/js/bootstrap.min.js (100%) > rename {htdocs => patchwork/static}/js/bundle.js (100%) > rename {htdocs => patchwork/static}/js/clipboard.min.js (100%) > create mode 120000 patchwork/static/js/jquery-1.10.1.min.js > create mode 120000 patchwork/static/js/jquery.checkboxes-1.0.6.min.js > create mode 120000 patchwork/static/js/jquery.stickytableheaders.min.js > create mode 120000 patchwork/static/js/jquery.tablednd.js > rename {htdocs => patchwork/static}/js/selectize.min.js (100%) > rename {templates => patchwork/templates}/404.html (100%) > rename {templates => patchwork/templates}/base.html (100%) > rename {templates => > patchwork/templates}/registration/password_change_done.html (100%) > rename {templates => > patchwork/templates}/registration/password_change_form.html (100%) > rename {templates => > patchwork/templates}/registration/password_reset_complete.html (100%) > rename {templates => > patchwork/templates}/registration/password_reset_confirm.html (100%) > rename {templates => > patchwork/templates}/registration/password_reset_done.html (100%) > rename {templates => > patchwork/templates}/registration/password_reset_email.html (100%) > rename {templates => > patchwork/templates}/registration/password_reset_form.html (100%) > create mode 100755 setup.py > > diff --git a/MANIFEST.in b/MANIFEST.in > new file mode 100644 > index 0000000..8d20fbf > --- /dev/null > +++ b/MANIFEST.in > @@ -0,0 +1,7 @@ > +include COPYING CONTRIBUTING.rst README.rst > +include requirements-prod.txt requirements-test.txt > +recursive-include patchwork/static *.js *.css *.png *.ico *.eot *.svg *.ttf > *.woff *.woff2 > +recursive-include patchwork/templates *.html *.txt > +recursive-include patchwork/fixtures *.xml > +graft docs > +prune docs/_build > diff --git a/htdocs/js/jquery-1.10.1.min.js b/htdocs/js/jquery-1.10.1.min.js > deleted file mode 120000 > index d48d893..0000000 > --- a/htdocs/js/jquery-1.10.1.min.js > +++ /dev/null > @@ -1 +0,0 @@ > -../../lib/packages/jquery/jquery-1.10.1.min.js > \ No newline at end of file > diff --git a/htdocs/js/jquery.checkboxes-1.0.6.min.js > b/htdocs/js/jquery.checkboxes-1.0.6.min.js > deleted file mode 120000 > index dfef5d4..0000000 > --- a/htdocs/js/jquery.checkboxes-1.0.6.min.js > +++ /dev/null > @@ -1 +0,0 @@ > -../../lib/packages/jquery/jquery.checkboxes-1.0.6.min.js > \ No newline at end of file > diff --git a/htdocs/js/jquery.stickytableheaders.min.js > b/htdocs/js/jquery.stickytableheaders.min.js > deleted file mode 120000 > index 0c22fa9..0000000 > --- a/htdocs/js/jquery.stickytableheaders.min.js > +++ /dev/null > @@ -1 +0,0 @@ > -../../lib/packages/jquery/jquery.stickytableheaders.min.js > \ No newline at end of file > diff --git a/htdocs/js/jquery.tablednd.js b/htdocs/js/jquery.tablednd.js > deleted file mode 120000 > index ed51ba1..0000000 > --- a/htdocs/js/jquery.tablednd.js > +++ /dev/null > @@ -1 +0,0 @@ > -../../lib/packages/jquery/jquery.tablednd.js > \ No newline at end of file > diff --git a/patchwork/settings/base.py b/patchwork/settings/base.py > index 001878a..e72d809 100644 > --- a/patchwork/settings/base.py > +++ b/patchwork/settings/base.py > @@ -5,7 +5,7 @@ Base settings for patchwork project. > import os > > ROOT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), > - os.pardir, os.pardir) > + os.pardir) > > # > # Core settings > @@ -97,7 +97,7 @@ SITE_ID = 1 > STATIC_URL = '/static/' > > STATICFILES_DIRS = [ > - os.path.join(ROOT_DIR, 'htdocs'), > + os.path.join(ROOT_DIR, 'static'), > ] > > # > diff --git a/htdocs/README.rst b/patchwork/static/README.rst > similarity index 100% > rename from htdocs/README.rst > rename to patchwork/static/README.rst > diff --git a/htdocs/css/bootstrap.min.css > b/patchwork/static/css/bootstrap.min.css > similarity index 100% > rename from htdocs/css/bootstrap.min.css > rename to patchwork/static/css/bootstrap.min.css > diff --git a/htdocs/css/selectize.bootstrap3.css > b/patchwork/static/css/selectize.bootstrap3.css > similarity index 100% > rename from htdocs/css/selectize.bootstrap3.css > rename to patchwork/static/css/selectize.bootstrap3.css > diff --git a/htdocs/css/style.css b/patchwork/static/css/style.css > similarity index 100% > rename from htdocs/css/style.css > rename to patchwork/static/css/style.css > diff --git a/htdocs/fonts/glyphicons-halflings-regular.eot > b/patchwork/static/fonts/glyphicons-halflings-regular.eot > similarity index 100% > rename from htdocs/fonts/glyphicons-halflings-regular.eot > rename to patchwork/static/fonts/glyphicons-halflings-regular.eot > diff --git a/htdocs/fonts/glyphicons-halflings-regular.svg > b/patchwork/static/fonts/glyphicons-halflings-regular.svg > similarity index 100% > rename from htdocs/fonts/glyphicons-halflings-regular.svg > rename to patchwork/static/fonts/glyphicons-halflings-regular.svg > diff --git a/htdocs/fonts/glyphicons-halflings-regular.ttf > b/patchwork/static/fonts/glyphicons-halflings-regular.ttf > similarity index 100% > rename from htdocs/fonts/glyphicons-halflings-regular.ttf > rename to patchwork/static/fonts/glyphicons-halflings-regular.ttf > diff --git a/htdocs/fonts/glyphicons-halflings-regular.woff > b/patchwork/static/fonts/glyphicons-halflings-regular.woff > similarity index 100% > rename from htdocs/fonts/glyphicons-halflings-regular.woff > rename to patchwork/static/fonts/glyphicons-halflings-regular.woff > diff --git a/htdocs/js/bootstrap.min.js b/patchwork/static/js/bootstrap.min.js > similarity index 100% > rename from htdocs/js/bootstrap.min.js > rename to patchwork/static/js/bootstrap.min.js > diff --git a/htdocs/js/bundle.js b/patchwork/static/js/bundle.js > similarity index 100% > rename from htdocs/js/bundle.js > rename to patchwork/static/js/bundle.js > diff --git a/htdocs/js/clipboard.min.js b/patchwork/static/js/clipboard.min.js > similarity index 100% > rename from htdocs/js/clipboard.min.js > rename to patchwork/static/js/clipboard.min.js > diff --git a/patchwork/static/js/jquery-1.10.1.min.js > b/patchwork/static/js/jquery-1.10.1.min.js > new file mode 120000 > index 0000000..659cd57 > --- /dev/null > +++ b/patchwork/static/js/jquery-1.10.1.min.js > @@ -0,0 +1 @@ > +../../../lib/packages/jquery/jquery-1.10.1.min.js > \ No newline at end of file > diff --git a/patchwork/static/js/jquery.checkboxes-1.0.6.min.js > b/patchwork/static/js/jquery.checkboxes-1.0.6.min.js > new file mode 120000 > index 0000000..8b3452b > --- /dev/null > +++ b/patchwork/static/js/jquery.checkboxes-1.0.6.min.js > @@ -0,0 +1 @@ > +../../../lib/packages/jquery/jquery.checkboxes-1.0.6.min.js > \ No newline at end of file > diff --git a/patchwork/static/js/jquery.stickytableheaders.min.js > b/patchwork/static/js/jquery.stickytableheaders.min.js > new file mode 120000 > index 0000000..7031ac1 > --- /dev/null > +++ b/patchwork/static/js/jquery.stickytableheaders.min.js > @@ -0,0 +1 @@ > +../../../lib/packages/jquery/jquery.stickytableheaders.min.js > \ No newline at end of file > diff --git a/patchwork/static/js/jquery.tablednd.js > b/patchwork/static/js/jquery.tablednd.js > new file mode 120000 > index 0000000..80574c4 > --- /dev/null > +++ b/patchwork/static/js/jquery.tablednd.js > @@ -0,0 +1 @@ > +../../../lib/packages/jquery/jquery.tablednd.js > \ No newline at end of file > diff --git a/htdocs/js/selectize.min.js b/patchwork/static/js/selectize.min.js > similarity index 100% > rename from htdocs/js/selectize.min.js > rename to patchwork/static/js/selectize.min.js > diff --git a/templates/404.html b/patchwork/templates/404.html > similarity index 100% > rename from templates/404.html > rename to patchwork/templates/404.html > diff --git a/templates/base.html b/patchwork/templates/base.html > similarity index 100% > rename from templates/base.html > rename to patchwork/templates/base.html > diff --git a/templates/registration/password_change_done.html > b/patchwork/templates/registration/password_change_done.html > similarity index 100% > rename from templates/registration/password_change_done.html > rename to patchwork/templates/registration/password_change_done.html > diff --git a/templates/registration/password_change_form.html > b/patchwork/templates/registration/password_change_form.html > similarity index 100% > rename from templates/registration/password_change_form.html > rename to patchwork/templates/registration/password_change_form.html > diff --git a/templates/registration/password_reset_complete.html > b/patchwork/templates/registration/password_reset_complete.html > similarity index 100% > rename from templates/registration/password_reset_complete.html > rename to patchwork/templates/registration/password_reset_complete.html > diff --git a/templates/registration/password_reset_confirm.html > b/patchwork/templates/registration/password_reset_confirm.html > similarity index 100% > rename from templates/registration/password_reset_confirm.html > rename to patchwork/templates/registration/password_reset_confirm.html > diff --git a/templates/registration/password_reset_done.html > b/patchwork/templates/registration/password_reset_done.html > similarity index 100% > rename from templates/registration/password_reset_done.html > rename to patchwork/templates/registration/password_reset_done.html > diff --git a/templates/registration/password_reset_email.html > b/patchwork/templates/registration/password_reset_email.html > similarity index 100% > rename from templates/registration/password_reset_email.html > rename to patchwork/templates/registration/password_reset_email.html > diff --git a/templates/registration/password_reset_form.html > b/patchwork/templates/registration/password_reset_form.html > similarity index 100% > rename from templates/registration/password_reset_form.html > rename to patchwork/templates/registration/password_reset_form.html > diff --git a/requirements-test.txt b/requirements-test.txt > index 5afe243..43af5ea 100644 > --- a/requirements-test.txt > +++ b/requirements-test.txt > @@ -2,4 +2,4 @@ mysqlclient~=1.4.4 > psycopg2-binary~=2.8.0 > sqlparse~=0.3.0 > python-dateutil~=2.8.0 > -https://github.com/p1c2u/openapi-core/archive/97ec8c796746f72ef3298fe92078b5f80e1f66f7.tar.gz > +git+https://github.com/p1c2u/openapi-core.git@97ec8c796746f72ef3298fe92078b5f80e1f66f7 > # openapi-core > diff --git a/setup.py b/setup.py > new file mode 100755 > index 0000000..0ea5fe4 > --- /dev/null > +++ b/setup.py > @@ -0,0 +1,69 @@ > +#!/usr/bin/env python > + > +import os > + > +from setuptools import setup, find_packages > + > + > +here = os.path.abspath(os.path.dirname(__file__)) > +with open(os.path.join(here, "README.rst")) as fd: > + README = fd.read() > + > + > +def get_requirements(requirements_file="requirements-prod.txt"): > + """Get the contents of a file listing the requirements. > + > + Args: > + requirements_file (str): The path to the requirements file, relative > + to this file. > + > + Returns: > + list: the list of requirements, or an empty list if > + ``requirements_file`` could not be opened or read. > + """ > + with open(requirements_file) as fd: > + lines = fd.readlines() > + dependencies = [] > + for line in lines: > + maybe_dep = line.strip() > + if maybe_dep.startswith("#"): > + # Skip pure comment lines > + continue > + if maybe_dep.startswith("git+"): > + # VCS reference for dev purposes, expect a trailing comment > + # with the normal requirement > + __, __, maybe_dep = maybe_dep.rpartition("#") > + else: > + # Ignore any trailing comment > + maybe_dep, __, __ = maybe_dep.partition("#") > + # Remove any whitespace and assume non-empty results are dependencies > + maybe_dep = maybe_dep.strip() > + if maybe_dep: > + dependencies.append(maybe_dep) > + return dependencies > + > + > +setup( > + name="patchwork", > + version="3.0.0a1", > + description="A patch tracking system for community-based projects.", > + long_description=README, > + url="https://github.com/getpatchwork/patchwork/", > + # Possible options are at > https://pypi.python.org/pypi?%3Aaction=list_classifiers > + classifiers=[ > + "Development Status :: 5 - Production/Stable", > + "Framework :: Django", > + "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", > + "Programming Language :: Python :: 3", > + "Programming Language :: Python :: 3.6", > + "Programming Language :: Python :: 3.7", > + "Programming Language :: Python :: 3.8", > + ], > + license="GPLv2", > + packages=find_packages(), > + include_package_data=True, > + zip_safe=False, > + install_requires=get_requirements(), > + > tests_require=get_requirements(requirements_file="requirements-test.txt"), > + test_suite="patchwork.tests", > +) _______________________________________________ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork