Hi, after a lengthy fight and several reconsideration, repo generation is here.
NOTE: If there is a copr at frontend, but no finished build in backend (which actually contains the baseurl - it's nowhere else in the system), 404 with an according error message is returned.
TR
From c9f3e24d288ed89297f6a255873e0a92429101e0 Mon Sep 17 00:00:00 2001
From: Tomas Radej tradej@redhat.com Date: Thu, 11 Apr 2013 12:50:15 +0200 Subject: [PATCH] Repo file generation
--- .../coprs/templates/coprs/coprchroot.repo | 7 ++++++ .../coprs/views/coprs_ns/coprs_general.py | 21 ++++++++++++++++ .../test_views/test_coprs_ns/test_coprs_general.py | 29 ++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 coprs_frontend/coprs/templates/coprs/coprchroot.repo
diff --git a/coprs_frontend/coprs/templates/coprs/coprchroot.repo b/coprs_frontend/coprs/templates/coprs/coprchroot.repo new file mode 100644 index 0000000..98d79d3 --- /dev/null +++ b/coprs_frontend/coprs/templates/coprs/coprchroot.repo @@ -0,0 +1,7 @@ +[{{ copr.owner.name }}-{{ copr.name }}] + +name=Copr repo for {{ copr.name }} owned by {{ copr.owner.name }} +description={{ copr.description }} +baseurl={{ url }} +skip_if_unavailable=True + diff --git a/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/coprs_frontend/coprs/views/coprs_ns/coprs_general.py index 9d5be98..ee4145d 100644 --- a/coprs_frontend/coprs/views/coprs_ns/coprs_general.py +++ b/coprs_frontend/coprs/views/coprs_ns/coprs_general.py @@ -16,6 +16,8 @@ from coprs.views.coprs_ns import coprs_ns from coprs.logic import builds_logic from coprs.logic import coprs_logic
+from sqlalchemy.orm.exc import NoResultFound + @coprs_ns.route('/', defaults = {'page': 1}) @coprs_ns.route('/int:page/') def coprs_show(page=1): @@ -272,3 +274,22 @@ def copr_legal_flag(username, coprname): db.session.commit() flask.flash('Admin was noticed about your report and will investigate the copr shortly.') return flask.redirect(flask.url_for('coprs_ns.copr_detail', username=username, coprname=coprname)) + +@coprs_ns.route('/detail/<username>/<coprname>/<chrootname>.repo', methods = ['GET']) +def generate_repo_file(username, coprname, chrootname): + ''' Generate repo file for a given copr/mock-chroot ''' + try: + # We're taking the baseurl from any finished build in the given copr. + # It's ugly, but so far we didn't come up with anything else. + copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname, + with_mock_chroots=True, with_builds=True).filter(models.Build.results != None).one() + except NoResultFound: + if not coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first(): + return page_not_found('Copr: {0}/{1} does not exist'.format(username, coprname)) + else: + return page_not_found('Repository not initialized: No builds in {0}/{1} are finished.'.format(username, coprname)) + + response = flask.make_response(flask.render_template('coprs/coprchroot.repo', copr=copr, url=copr.builds[0].results)) + response.mimetype='text/plain' + return response + diff --git a/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py b/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py index 380d59d..ad4a77c 100644 --- a/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py +++ b/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py @@ -1,8 +1,10 @@ import flask +import pytest
from flexmock import flexmock
from coprs.signals import copr_created +from coprs import models
from tests.coprs_test_case import CoprsTestCase
@@ -456,3 +458,30 @@ class TestCoprDelete(CoprsTestCase): assert 'Copr was deleted successfully' not in r.data assert not self.models.Action.query.first() assert self.models.Copr.query.filter(self.models.Copr.id==self.c1.id).first() + +class TestCoprRepoGeneration(CoprsTestCase): + @pytest.fixture + def f_custom_builds(self): + ''' Custom builds are used in order not to break the default ones ''' + self.b5 = models.Build(copr=self.c1, user=self.u1, chroots='fedora-18-x86_64', submitted_on=9, ended_on=200, results='foo://bar.baz') + self.b6 = models.Build(copr=self.c1, user=self.u1, chroots='fedora-18-x86_64', submitted_on=11) + self.b7 = models.Build(copr=self.c1, user=self.u1, chroots='fedora-18-x86_64', submitted_on=10, ended_on=150, results='foo://bar.baz') + + self.db.session.add_all([self.b5, self.b6, self.b7]) + + def test_fail_on_no_copr(self): + r = self.tc.get('/coprs/detail/bogus/copr/name.repo') + assert r.status_code == 404 + assert 'bogus/copr does not exist' in r.data + + def test_fail_on_no_finished_builds(self, f_users, f_coprs, f_mock_chroots, f_db): + r = self.tc.get( + '/coprs/detail/{0}/{1}/{2}.repo'.format(self.u1.name, self.c1.name, + self.c1.mock_chroots[0].chroot_name)) + assert r.status_code == 404 + assert 'Repository not initialized' in r.data + + def test_older_and_newer_builds_give_same_url(self, f_users, f_coprs, f_mock_chroots, f_custom_builds, f_db): + r = self.tc.get('/coprs/detail/{0}/{1}/{2}.repo'.format(self.u1.name, self.c1.name, self.c1.mock_chroots[0].chroot_name)) + assert r.status_code == 200 + assert 'baseurl=foo://bar.baz' in r.data
----- Original Message -----
Hi, after a lengthy fight and several reconsideration, repo generation is here.
NOTE: If there is a copr at frontend, but no finished build in backend (which actually contains the baseurl - it's nowhere else in the system), 404 with an according error message is returned.
TR
<snip>
Thanks Tomas, looks good. Since you want to participate more, I don't see why I wouldn't give you commit rights to copr git - of course you would have to promise you'll be gentle to the current code ;) So, does anyone has any objections? If none are raised before next Wednesday, I'll go on and make Tomas our commiter.
Thanks, Slavek.
On Fri, 19 Apr 2013 02:04:37 -0400 (EDT) Bohuslav Kabrda bkabrda@redhat.com wrote:
----- Original Message -----
Hi, after a lengthy fight and several reconsideration, repo generation is here.
NOTE: If there is a copr at frontend, but no finished build in backend (which actually contains the baseurl - it's nowhere else in the system), 404 with an according error message is returned.
TR
<snip>
Thanks Tomas, looks good. Since you want to participate more, I don't see why I wouldn't give you commit rights to copr git - of course you would have to promise you'll be gentle to the current code ;) So, does anyone has any objections? If none are raised before next Wednesday, I'll go on and make Tomas our commiter.
None - I can add him to the group right now, or you can. I think we are both 'admins' for the group.
-sv
On Thu, 2013-04-18 at 14:24 +0200, Tomas Radej wrote:
- try:
# We're taking the baseurl from any finished build in the
given copr.
# It's ugly, but so far we didn't come up with anything else.
copr = coprs_logic.CoprsLogic.get(flask.g.user, username,
coprname,
with_mock_chroots=True,
with_builds=True).filter(models.Build.results != None).one()
- except NoResultFound:
if not coprs_logic.CoprsLogic.get(flask.g.user, username,
coprname).first():
return page_not_found('Copr: {0}/{1} does not
exist'.format(username, coprname))
else:
return page_not_found('Repository not initialized: No
builds in {0}/{1} are finished.'.format(username, coprname))
I don't know how much we're already doing it in the current code so the question is more style related. Do we want to have sql (ie SQLAlchemy query) in the controller?
Personally, I'm not fan of it since it means that if one day the ORM changes, there is code to change all over the place. But that's just my personal preference :)
Pierre
----- Original Message -----
On Thu, 2013-04-18 at 14:24 +0200, Tomas Radej wrote:
- try:
# We're taking the baseurl from any finished build in the
given copr.
# It's ugly, but so far we didn't come up with anything else.
copr = coprs_logic.CoprsLogic.get(flask.g.user, username,
coprname,
with_mock_chroots=True,
with_builds=True).filter(models.Build.results != None).one()
- except NoResultFound:
if not coprs_logic.CoprsLogic.get(flask.g.user, username,
coprname).first():
return page_not_found('Copr: {0}/{1} does not
exist'.format(username, coprname))
else:
return page_not_found('Repository not initialized: No
builds in {0}/{1} are finished.'.format(username, coprname))
I don't know how much we're already doing it in the current code so the question is more style related. Do we want to have sql (ie SQLAlchemy query) in the controller?
Personally, I'm not fan of it since it means that if one day the ORM changes, there is code to change all over the place. But that's just my personal preference :)
Pierre
Good point, Pierre. I'm not quite sure about usage of sqlalchemy in views right now, but I guess it's minimal and it's true that keeping it that way is a good idea. So Tomas, maybe you could modify CoprsLogic.get to accept an argument like ended_builds_only, which would change the with_builds behaviour in a proper way? And this should probably actually return the copr even if no ended builds are found (which would simplify your view code, but will probably require using a subselect query or so).
Thanks, Slavek.
copr-devel@lists.stg.fedorahosted.org