Skip to content

Commit c6ca616

Browse files
committed
[IMP] runbot: batch show file0
1 parent 31c3fe7 commit c6ca616

3 files changed

Lines changed: 58 additions & 13 deletions

File tree

runbot/models/build.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,15 +1126,21 @@ def _get_modules_to_test(self, modules_patterns=''):
11261126
def _dependency_graph(self):
11271127
dependency_graph = defaultdict(set)
11281128
dependant_graph = defaultdict(set)
1129-
for commit, addons_path, module, manifest_file_name in self._list_available_modules():
1130-
manifest = commit._git_show_file(os.path.join(addons_path, module, manifest_file_name))
1131-
manifest_content = ast.literal_eval(manifest)
1132-
depends = manifest_content.get('depends', [])
1133-
if not depends and module != 'base':
1134-
depends = ['base']
1135-
for dep in depends:
1136-
dependency_graph[module].add(dep)
1137-
dependant_graph[dep].add(module)
1129+
for commit in self.env.context.get('defined_commit_ids') or self.params_id.commit_ids:
1130+
file_paths = []
1131+
modules = []
1132+
for (addons_path, module, manifest_file_name) in commit._list_available_modules():
1133+
file_paths.append(os.path.join(addons_path, module, manifest_file_name))
1134+
modules.append(module)
1135+
contents = commit._git_show_files(file_paths)
1136+
for module, manifest in zip(modules, contents):
1137+
manifest_content = ast.literal_eval(manifest)
1138+
depends = manifest_content.get('depends', [])
1139+
if not depends and module != 'base':
1140+
depends = ['base']
1141+
for dep in depends:
1142+
dependency_graph[module].add(dep)
1143+
dependant_graph[dep].add(module)
11381144
return dependency_graph, dependant_graph
11391145

11401146
def search_modules_graph(self, modules, graph, depth=None):

runbot/models/commit.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,43 @@ def _read_source(self, file, mode='r'):
163163

164164
@transactioncache
165165
def _git_show_file(self, file):
166+
return self._git_show_files([file])[0]
167+
168+
def _git_show_files(self, files):
166169
self.ensure_one()
170+
if not files:
171+
return []
172+
167173
self.repo_id._fetch(self.name)
174+
175+
queries = "\n".join([f"{self.name}:{f}" for f in files]) + "\n"
176+
168177
try:
169-
return self.repo_id._git(['show', '%s:%s' % (self.name, file)])
178+
buffer = self.repo_id._git(
179+
['cat-file', '--batch'],
180+
input_data=queries,
181+
raw=True,
182+
)
170183
except subprocess.CalledProcessError:
171-
return False
184+
return [False] * len(files)
185+
186+
results = []
187+
offset = 0
188+
buffer_len = len(buffer)
189+
while offset < buffer_len:
190+
newline_idx = buffer.find(b'\n', offset)
191+
if newline_idx == -1:
192+
break
193+
header = buffer[offset:newline_idx].decode('utf-8')
194+
offset = newline_idx + 1
195+
try:
196+
size_in_bytes = int(header.rsplit(' ',1)[-1])
197+
except ValueError: # most likely missing
198+
results.append(False)
199+
continue
200+
results.append(buffer[offset : offset + size_in_bytes].decode('utf-8', errors='replace'))
201+
offset += size_in_bytes + 1
202+
return results
172203

173204
def _source_path(self, *paths):
174205
if not self.tree_hash:

runbot/models/repo.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,11 +503,19 @@ def _get_git_command(self, cmd, errors='strict'):
503503
cmd = ['git', '-C', self.path] + config_args + cmd
504504
return cmd
505505

506-
def _git(self, cmd, errors='strict', quiet=False):
506+
def _git(self, cmd, errors='strict', quiet=False, input_data=None, raw=False):
507507
cmd = self._get_git_command(cmd, errors)
508508
if not quiet:
509509
_logger.info("git command: %s", shlex.join(cmd))
510-
return subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode(errors=errors)
510+
kwargs = {'stderr': subprocess.STDOUT}
511+
if input_data is not None:
512+
if isinstance(input_data, str):
513+
input_data = input_data.encode('utf-8')
514+
kwargs['input'] = input_data
515+
output = subprocess.check_output(cmd, **kwargs)
516+
if raw:
517+
return output
518+
return output.decode(errors=errors)
511519

512520
def _fetch(self, sha):
513521
if not self._hash_exists(sha):

0 commit comments

Comments
 (0)