Message ID | 20200428213613.280483-1-jcline@redhat.com |
---|---|
State | Rejected |
Headers | show |
Series | [RFC] Add a setup.py so Patchwork can be pip-installed | expand |
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 <jcline@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", > +)
Hi Stephen, On Thu, May 07, 2020 at 02:29:30PM +0100, Stephen Finucane wrote: > 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? > No worries about the delay, thanks for taking a look. What I'm doing is a bit odd, I suppose, but perhaps explaining what I'm up to will make things clearer. We've got some people who like developing via email, and some people who want to use GitLab, so I decided to just bridge the two so patches and reviews end up as emails and merge requests regardless of where they're submitted. Of course, parsing and tracking the email is a big job, but Patchwork has already done all the hard work so... I created another Django application that depends on Patchwork, adds a few new URLs, and includes a few event handlers on the Patchwork database models. So even though it's not really the intention of Patchwork, I'm using it a bit like a library and being able to express the dependency in my own Python package is handy. One of the great things about Django apps are their reusability (even if you never imagined anyone would do something so silly) and bundling them up in Python packages makes it much easier to extend. It also, I think, simplifies your installation documentation because instead of having people untar the release and potentially mess with their Python path it becomes a simple "pip install". I am using this in addition to an Ansible role so it's not a *huge* deal, it's just a bit awkward. Thanks, Jeremy
Jeremy Cline <jcline@redhat.com> writes: > Hi Stephen, > > On Thu, May 07, 2020 at 02:29:30PM +0100, Stephen Finucane wrote: >> 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. I'm not generally opposed to having a setup.py, but the moving around of files worries me a little bit; I'd want to check to see it doesn't break anyone using a webserver to serve the static files directly without going through Django. It probably does! - I just want to check and be sure before we merge it. >> > >> > 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? >> > > No worries about the delay, thanks for taking a look. > > What I'm doing is a bit odd, I suppose, but perhaps explaining what I'm > up to will make things clearer. We've got some people who like > developing via email, and some people who want to use GitLab, so I > decided to just bridge the two so patches and reviews end up as emails > and merge requests regardless of where they're submitted. Of course, > parsing and tracking the email is a big job, but Patchwork has already > done all the hard work so... > > I created another Django application that depends on Patchwork, adds a > few new URLs, and includes a few event handlers on the Patchwork > database models. So even though it's not really the intention of > Patchwork, I'm using it a bit like a library and being able to express > the dependency in my own Python package is handy. > Nifty. -- d > One of the great things about Django apps are their reusability (even if > you never imagined anyone would do something so silly) and bundling them > up in Python packages makes it much easier to extend. It also, I think, > simplifies your installation documentation because instead of having > people untar the release and potentially mess with their Python path it > becomes a simple "pip install". > > I am using this in addition to an Ansible role so it's not a *huge* > deal, it's just a bit awkward. > > Thanks, > Jeremy > > _______________________________________________ > Patchwork mailing list > Patchwork@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/patchwork
Daniel Axtens <dja@axtens.net> writes: > Jeremy Cline <jcline@redhat.com> writes: > >> Hi Stephen, >> >> On Thu, May 07, 2020 at 02:29:30PM +0100, Stephen Finucane wrote: >>> 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. > > I'm not generally opposed to having a setup.py, but the moving around of > files worries me a little bit; I'd want to check to see it doesn't break > anyone using a webserver to serve the static files directly without > going through Django. It probably does! - I just want to check and be * s/It probably does!/It probably doesn't break anything!/ >>> > >>> > 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? >>> >> >> No worries about the delay, thanks for taking a look. >> >> What I'm doing is a bit odd, I suppose, but perhaps explaining what I'm >> up to will make things clearer. We've got some people who like >> developing via email, and some people who want to use GitLab, so I >> decided to just bridge the two so patches and reviews end up as emails >> and merge requests regardless of where they're submitted. Of course, >> parsing and tracking the email is a big job, but Patchwork has already >> done all the hard work so... >> >> I created another Django application that depends on Patchwork, adds a >> few new URLs, and includes a few event handlers on the Patchwork >> database models. So even though it's not really the intention of >> Patchwork, I'm using it a bit like a library and being able to express >> the dependency in my own Python package is handy. >> > > Nifty. > > -- d > >> One of the great things about Django apps are their reusability (even if >> you never imagined anyone would do something so silly) and bundling them >> up in Python packages makes it much easier to extend. It also, I think, >> simplifies your installation documentation because instead of having >> people untar the release and potentially mess with their Python path it >> becomes a simple "pip install". >> >> I am using this in addition to an Ansible role so it's not a *huge* >> deal, it's just a bit awkward. >> >> Thanks, >> Jeremy >> >> _______________________________________________ >> Patchwork mailing list >> Patchwork@lists.ozlabs.org >> https://lists.ozlabs.org/listinfo/patchwork
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", +)
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. Signed-off-by: Jeremy Cline <jcline@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