Skip to content

Commit b582d56

Browse files
authored
Merge pull request #386 from irushchyshyn/feature/build-requires-ui
Load build dependencies into the database
2 parents e195af0 + 2b5e686 commit b582d56

6 files changed

Lines changed: 110 additions & 27 deletions

File tree

portingdb/cli.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,12 @@ def report(ctx):
170170
query = db.query(tables.Package)
171171
query = query.order_by(func.lower(tables.Package.name))
172172
query = query.options(eagerload(tables.Package.by_collection))
173-
query = query.options(subqueryload(tables.Package.requirements))
173+
query = query.options(subqueryload(tables.Package.run_time_requirements))
174174
for package in query:
175175
print_collection_info(package, collections)
176176
print(' ' + package.name, end=' ')
177177
reqs = []
178-
for req in package.requirements:
178+
for req in package.run_time_requirements:
179179
for cp in req.by_collection.values():
180180
if cp.status not in ('released', 'legacy-leaf', 'py3-only'):
181181
reqs.append(req.name)
@@ -262,7 +262,7 @@ def can_ignore(pkg):
262262
e = '✔'
263263
else:
264264
seen.add(pkg)
265-
reqs = [p for p in pkg.requirements if p is not pkg]
265+
reqs = [p for p in pkg.run_time_requirements if p is not pkg]
266266
if skip:
267267
reqs = [r for r in reqs
268268
if not (can_ignore(r) or r.name in exclude)]

portingdb/htmlreport.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,15 @@ def package(pkg):
210210

211211
dependents = list(queries.dependents(db, package))
212212

213+
query = queries.build_dependencies(db, package)
214+
query = query.options(eagerload('status_obj'))
215+
query = query.options(subqueryload('collection_packages'))
216+
query = query.options(subqueryload('collection_packages.links'))
217+
query = query.options(eagerload('collection_packages.status_obj'))
218+
build_dependencies = list(query)
219+
220+
build_dependents = list(queries.build_dependents(db, package))
221+
213222
return render_template(
214223
'package.html',
215224
breadcrumbs=(
@@ -221,8 +230,11 @@ def package(pkg):
221230
dependencies=dependencies,
222231
dependents=dependents,
223232
deptree=[(package, gen_deptree(dependencies))],
224-
len_dependencies=len(dependencies),
225233
dependencies_status_counts=get_status_counts(dependencies),
234+
build_dependencies=build_dependencies,
235+
build_dependents=build_dependents,
236+
build_deptree=[(package, gen_deptree(build_dependencies, run_time=False, build_time=True))],
237+
build_dependencies_status_counts=get_status_counts(build_dependencies),
226238
)
227239

228240

@@ -258,21 +270,24 @@ def group(grp):
258270
grp=group,
259271
packages=packages,
260272
len_packages=len(packages),
261-
deptree=list(gen_deptree(seed_groups)),
273+
deptree=list(gen_deptree(seed_groups, run_time=True, build_time=True)),
262274
status_counts=get_status_counts(packages),
263275
)
264276

265277

266-
def gen_deptree(base, *, seen=None):
278+
def gen_deptree(base, *, seen=None, run_time=True, build_time=False):
267279
seen = seen or set()
268280
base = tuple(base)
269281
for pkg in base:
270282
if pkg in seen or pkg.status in {'idle'} | DONE_STATUSES:
271283
yield pkg, []
272284
else:
273-
reqs = sorted(pkg.requirements,
274-
key=lambda p: (-p.status_obj.weight, p.name))
275-
yield pkg, gen_deptree(reqs, seen=seen | {pkg})
285+
reqs = sorted(
286+
set((pkg.run_time_requirements if run_time else []) +
287+
(pkg.build_time_requirements if build_time else [])),
288+
key=lambda p: (-p.status_obj.weight, p.name))
289+
yield pkg, gen_deptree(reqs, seen=seen | {pkg},
290+
run_time=run_time, build_time=build_time)
276291
seen.add(pkg)
277292

278293

@@ -347,7 +362,7 @@ def graph_json(grp=None, pkg=None):
347362
if grp:
348363
query = query.join(tables.GroupPackage)
349364
query = query.filter(tables.GroupPackage.group_ident == grp)
350-
query = query.options(joinedload(tables.Package.requirers))
365+
query = query.options(joinedload(tables.Package.run_time_requirers))
351366
packages = list(query)
352367
else:
353368
query = db.query(tables.Package)
@@ -360,20 +375,21 @@ def graph_json(grp=None, pkg=None):
360375
package = todo.pop()
361376
if package not in requirements:
362377
requirements.add(package)
363-
todo.update(p for p in package.requirements
378+
todo.update(p for p in package.run_time_requirements
364379
if p.status not in DONE_STATUSES)
365380
todo = {root_package}
366381
requirers = set()
367382
while todo:
368383
package = todo.pop()
369384
if package not in requirers:
370385
requirers.add(package)
371-
todo.update(p for p in package.requirers
386+
todo.update(p for p in package.run_time_requirers
372387
if p.status not in DONE_STATUSES)
373388
packages = list(requirements | requirers | {root_package})
374389

375390
package_names = {p.name for p in packages}
376391
query = db.query(tables.Dependency)
392+
query = query.filter(tables.Dependency.run_time)
377393
linked_pairs = {(d.requirer_name, d.requirement_name)
378394
for d in query
379395
if d.requirer_name in package_names

portingdb/load.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -230,18 +230,33 @@ def load_from_directories(db, directories):
230230
bulk_load(db, values, tables.Package.__table__, id_column="name")
231231

232232
# Dependencies
233-
values = [{'requirer_name': a, 'requirement_name': b, 'unversioned': False}
234-
for a, v in package_infos.items() for b in v.get('deps', ())
235-
if a != b]
233+
ambiguous_deps = {}
236234
for requirement, info in package_infos.items():
237235
for requirer in info.get('unversioned_requirers', ()):
238-
row = {'requirer_name': requirer,
239-
'requirement_name': requirement,
240-
'unversioned': False}
241-
if row in values:
242-
values.remove(row)
243-
row['unversioned'] = True
244-
values.append(row)
236+
ambiguous_deps[(requirer, requirement)] = True
237+
238+
values = []
239+
for package, info in package_infos.items():
240+
for dep in set(info.get('deps', ()) + info.get('build_deps', ())):
241+
if package != dep:
242+
values.append(
243+
{'requirer_name': package,
244+
'requirement_name': dep,
245+
'run_time': dep in info.get('deps', ()),
246+
'build_time': dep in info.get('build_deps', ()),
247+
'unversioned': ambiguous_deps.pop((package, dep), False)}
248+
)
249+
250+
# Add the rest of ambiguous deps, which are not in portingdb (non-Python).
251+
for requirer, requirement in ambiguous_deps:
252+
values.append(
253+
{'requirer_name': requirer,
254+
'requirement_name': requirement,
255+
# Ambiguous deps are not categorized into build
256+
# and run time. And do not need to be.
257+
'run_time': False, 'build_time': False,
258+
'unversioned': True}
259+
)
245260

246261
bulk_load(db, values, tables.Dependency.__table__,
247262
key_columns=['requirer_name', 'requirement_name'])

portingdb/queries.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ def order_by_weight(db, query):
3838
return query
3939

4040

41-
def _deps(db, package, forward=True):
41+
def _deps(db, package, forward=True, run_time=True, build_time=False):
4242
query = packages(db)
43-
package_table = aliased(tables.Package)
4443

4544
if forward:
4645
col_a = tables.Dependency.requirement_name
@@ -51,6 +50,10 @@ def _deps(db, package, forward=True):
5150
query = query.outerjoin(tables.Dependency, col_a == tables.Package.name)
5251
query = query.filter(col_b == package.name)
5352

53+
query = query.filter(
54+
or_(tables.Dependency.run_time == run_time,
55+
tables.Dependency.build_time == build_time))
56+
5457
query = query.join(tables.Status, tables.Status.ident == tables.Package.status)
5558
query = query.order_by(-tables.Status.weight)
5659
query = order_by_name(db, query)
@@ -66,6 +69,14 @@ def dependents(db, package):
6669
return _deps(db, package, False)
6770

6871

72+
def build_dependencies(db, package):
73+
return _deps(db, package, True, False, True)
74+
75+
76+
def build_dependents(db, package):
77+
return _deps(db, package, False, False, True)
78+
79+
6980
def order_by_name(db, query):
7081
return query.order_by(func.lower(tables.Package.name))
7182

@@ -115,6 +126,7 @@ def update_status_summaries(db):
115126
subquery = subquery.join(tables.Dependency, tables.Dependency.requirement_name == dep.name)
116127
subquery = subquery.filter(tables.Dependency.requirer_name == tables.Package.name)
117128
subquery = subquery.filter(tables.Dependency.requirer_name != tables.Dependency.requirement_name)
129+
subquery = subquery.filter(tables.Dependency.run_time)
118130

119131
update = main_update
120132
update = update.where(subquery.exists())

portingdb/tables.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from sqlalchemy import Column, ForeignKey, MetaData, extract, desc
2-
from sqlalchemy import UniqueConstraint
2+
from sqlalchemy import UniqueConstraint, and_
33
from sqlalchemy.types import Boolean, Integer, Unicode, UnicodeText, Date, DateTime
44
from sqlalchemy.types import Enum
55
from sqlalchemy.orm import backref, relationship
@@ -154,12 +154,12 @@ def __repr__(self):
154154

155155
@property
156156
def pending_requirements(self):
157-
return [r for r in self.requirements
157+
return [r for r in self.run_time_requirements
158158
if r.status not in ('released', 'dropped', 'py3-only', 'legacy-leaf')]
159159

160160
@property
161161
def pending_requirers(self):
162-
return [r for r in self.requirers
162+
return [r for r in self.run_time_requirers
163163
if r.status not in ('released', 'dropped', 'py3-only', 'legacy-leaf')]
164164

165165
@property
@@ -285,6 +285,8 @@ class Dependency(TableBase):
285285
unversioned = Column(
286286
Boolean(), default=False,
287287
doc=u"True if the requirement name should be changed to a versioned one")
288+
build_time = Column(Boolean())
289+
run_time = Column(Boolean())
288290

289291
requirer = relationship(
290292
'Package', backref=backref('requirement_dependencies'),
@@ -487,6 +489,20 @@ class HistoryNamingEntry(TableBase):
487489
secondaryjoin=Package.name == Dependency.requirement_name,
488490
backref="requirers")
489491

492+
Package.run_time_requirements = relationship(
493+
Package,
494+
secondary=Dependency.__table__,
495+
primaryjoin=and_(Package.name == Dependency.requirer_name, Dependency.run_time),
496+
secondaryjoin=Package.name == Dependency.requirement_name,
497+
backref="run_time_requirers")
498+
499+
Package.build_time_requirements = relationship(
500+
Package,
501+
secondary=Dependency.__table__,
502+
primaryjoin=and_(Package.name == Dependency.requirer_name, Dependency.build_time),
503+
secondaryjoin=Package.name == Dependency.requirement_name,
504+
backref="build_time_requirers")
505+
490506
Package.groups = relationship(
491507
Group,
492508
secondary=GroupPackage.__table__,

portingdb/templates/package.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ <h3>
122122
{% endif %}
123123
{% endfor %}
124124
<h3>Dependent packages</h3>
125+
<h4>Run time</h4>
125126
{% if dependents %}
126127
<ul class="simple-pkg-list">
127128
{% for pkg in dependents %}
@@ -131,8 +132,21 @@ <h3>Dependent packages</h3>
131132
{% else %}
132133
None.
133134
{% endif %}
135+
<h4>Build time</h4>
136+
{% if build_dependents %}
137+
<ul class="simple-pkg-list">
138+
{% for pkg in build_dependents %}
139+
<li>{{ pkglink(pkg) }}</li>
140+
{% endfor %}
141+
</ul>
142+
{% else %}
143+
None.
144+
{% endif %}
134145
<h3>Dependency Tree</h3>
146+
<h4>Run time</h4>
135147
{{ print_deptree(deptree) }}
148+
<h4>Build time</h4>
149+
{{ print_deptree(build_deptree) }}
136150
{% if pkg['loc_total'] %}
137151
<h3>Project Size</h3>
138152
{{ loc_chart(pkg) }}
@@ -181,6 +195,7 @@ <h3>Groups</h3>
181195
<div class="col-md-1"></div>
182196
<div class="col-md-8">
183197
<h2>Dependencies</h2>
198+
<h4>Run time</h4>
184199
{{ progress_summary_legend(dependencies_status_counts.items()) }}
185200
{% if dependencies %}
186201
<table class="table table-striped table-condensed table-hovered">
@@ -189,6 +204,15 @@ <h2>Dependencies</h2>
189204
{% else %}
190205
None.
191206
{% endif %}
207+
<h4>Build time</h4>
208+
{{ progress_summary_legend(build_dependencies_status_counts.items()) }}
209+
{% if build_dependencies %}
210+
<table class="table table-striped table-condensed table-hovered">
211+
{{ pkglist_table_content(build_dependencies, collections, show_nonblocking=1) }}
212+
</table>
213+
{% else %}
214+
None.
215+
{% endif %}
192216
</div>
193217
</div>
194218
{% endblock bodycontent %}

0 commit comments

Comments
 (0)