archvies: allowing to obtain archives without the commit short id in the name for better automation of obtained artifacts.
This commit is contained in:
parent
8791b52422
commit
130b6f4574
4 changed files with 56 additions and 39 deletions
|
|
@ -325,6 +325,21 @@ class RepoFilesView(RepoAppView):
|
|||
|
||||
return lf_enabled
|
||||
|
||||
def _get_archive_name(self, db_repo_name, commit_sha, ext, subrepos=False, path_sha=''):
|
||||
# original backward compat name of archive
|
||||
clean_name = safe_str(db_repo_name.replace('/', '_'))
|
||||
|
||||
# e.g vcsserver.zip
|
||||
# e.g vcsserver-abcdefgh.zip
|
||||
# e.g vcsserver-abcdefgh-defghijk.zip
|
||||
archive_name = '{}{}{}{}{}'.format(
|
||||
clean_name,
|
||||
'-sub' if subrepos else '',
|
||||
commit_sha,
|
||||
'-{}'.format(path_sha) if path_sha else '',
|
||||
ext)
|
||||
return archive_name
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
'repository.read', 'repository.write', 'repository.admin')
|
||||
|
|
@ -339,6 +354,7 @@ class RepoFilesView(RepoAppView):
|
|||
default_at_path = '/'
|
||||
fname = self.request.matchdict['fname']
|
||||
subrepos = self.request.GET.get('subrepos') == 'true'
|
||||
with_hash = str2bool(self.request.GET.get('with_hash', '1'))
|
||||
at_path = self.request.GET.get('at_path') or default_at_path
|
||||
|
||||
if not self.db_repo.enable_downloads:
|
||||
|
|
@ -364,26 +380,26 @@ class RepoFilesView(RepoAppView):
|
|||
except Exception:
|
||||
return Response(_('No node at path {} for this repository').format(at_path))
|
||||
|
||||
path_sha = sha1(at_path)[:8]
|
||||
# path sha is part of subdir
|
||||
path_sha = ''
|
||||
if at_path != default_at_path:
|
||||
path_sha = sha1(at_path)[:8]
|
||||
short_sha = '-{}'.format(safe_str(commit.short_id))
|
||||
# used for cache etc
|
||||
archive_name = self._get_archive_name(
|
||||
self.db_repo_name, commit_sha=short_sha, ext=ext, subrepos=subrepos,
|
||||
path_sha=path_sha)
|
||||
|
||||
# original backward compat name of archive
|
||||
clean_name = safe_str(self.db_repo_name.replace('/', '_'))
|
||||
short_sha = safe_str(commit.short_id)
|
||||
if not with_hash:
|
||||
short_sha = ''
|
||||
path_sha = ''
|
||||
|
||||
if at_path == default_at_path:
|
||||
archive_name = '{}-{}{}{}'.format(
|
||||
clean_name,
|
||||
'-sub' if subrepos else '',
|
||||
short_sha,
|
||||
ext)
|
||||
# custom path and new name
|
||||
else:
|
||||
archive_name = '{}-{}{}-{}{}'.format(
|
||||
clean_name,
|
||||
'-sub' if subrepos else '',
|
||||
short_sha,
|
||||
path_sha,
|
||||
ext)
|
||||
# what end client gets served
|
||||
response_archive_name = self._get_archive_name(
|
||||
self.db_repo_name, commit_sha=short_sha, ext=ext, subrepos=subrepos,
|
||||
path_sha=path_sha)
|
||||
# remove extension from our archive directory name
|
||||
archive_dir_name = response_archive_name[:-len(ext)]
|
||||
|
||||
use_cached_archive = False
|
||||
archive_cache_enabled = CONFIG.get(
|
||||
|
|
@ -403,13 +419,15 @@ class RepoFilesView(RepoAppView):
|
|||
else:
|
||||
log.debug('Archive %s is not yet cached', archive_name)
|
||||
|
||||
# generate new archive, as previous was not found in the cache
|
||||
if not use_cached_archive:
|
||||
# generate new archive
|
||||
|
||||
fd, archive = tempfile.mkstemp()
|
||||
log.debug('Creating new temp archive in %s', archive)
|
||||
try:
|
||||
commit.archive_repo(archive, kind=fileformat, subrepos=subrepos,
|
||||
archive_at_path=at_path)
|
||||
commit.archive_repo(archive, archive_dir_name=archive_dir_name,
|
||||
kind=fileformat, subrepos=subrepos,
|
||||
archive_at_path=at_path, with_hash=with_hash)
|
||||
except ImproperArchiveTypeError:
|
||||
return _('Unknown archive type')
|
||||
if archive_cache_enabled:
|
||||
|
|
@ -445,8 +463,7 @@ class RepoFilesView(RepoAppView):
|
|||
yield data
|
||||
|
||||
response = Response(app_iter=get_chunked_archive(archive))
|
||||
response.content_disposition = str(
|
||||
'attachment; filename=%s' % archive_name)
|
||||
response.content_disposition = str('attachment; filename=%s' % response_archive_name)
|
||||
response.content_type = str(content_type)
|
||||
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -1192,13 +1192,14 @@ class BaseCommit(object):
|
|||
return None
|
||||
|
||||
def archive_repo(self, archive_dest_path, kind='tgz', subrepos=None,
|
||||
prefix=None, write_metadata=False, mtime=None, archive_at_path='/'):
|
||||
archive_dir_name=None, write_metadata=False, mtime=None,
|
||||
archive_at_path='/', with_hash=True):
|
||||
"""
|
||||
Creates an archive containing the contents of the repository.
|
||||
|
||||
:param archive_dest_path: path to the file which to create the archive.
|
||||
:param kind: one of following: ``"tbz2"``, ``"tgz"``, ``"zip"``.
|
||||
:param prefix: name of root directory in archive.
|
||||
:param archive_dir_name: name of root directory in archive.
|
||||
Default is repository name and commit's short_id joined with dash:
|
||||
``"{repo_name}-{short_id}"``.
|
||||
:param write_metadata: write a metadata file into archive.
|
||||
|
|
@ -1214,7 +1215,7 @@ class BaseCommit(object):
|
|||
'Archive kind (%s) not supported use one of %s' %
|
||||
(kind, allowed_kinds))
|
||||
|
||||
prefix = self._validate_archive_prefix(prefix)
|
||||
archive_dir_name = self._validate_archive_prefix(archive_dir_name)
|
||||
|
||||
mtime = mtime is not None or time.mktime(self.date.timetuple())
|
||||
|
||||
|
|
@ -1222,7 +1223,7 @@ class BaseCommit(object):
|
|||
cur_rev = self.repository.get_commit(commit_id=self.raw_id)
|
||||
for _r, _d, files in cur_rev.walk(archive_at_path):
|
||||
for f in files:
|
||||
f_path = os.path.join(prefix, f.path)
|
||||
f_path = os.path.join(archive_dir_name, f.path)
|
||||
file_info.append(
|
||||
(f_path, f.mode, f.is_link(), f.raw_bytes))
|
||||
|
||||
|
|
@ -1239,18 +1240,18 @@ class BaseCommit(object):
|
|||
|
||||
connection.Hg.archive_repo(archive_dest_path, mtime, file_info, kind)
|
||||
|
||||
def _validate_archive_prefix(self, prefix):
|
||||
if prefix is None:
|
||||
prefix = self._ARCHIVE_PREFIX_TEMPLATE.format(
|
||||
def _validate_archive_prefix(self, archive_dir_name):
|
||||
if archive_dir_name is None:
|
||||
archive_dir_name = self._ARCHIVE_PREFIX_TEMPLATE.format(
|
||||
repo_name=safe_str(self.repository.name),
|
||||
short_id=self.short_id)
|
||||
elif not isinstance(prefix, str):
|
||||
raise ValueError("prefix not a bytes object: %s" % repr(prefix))
|
||||
elif prefix.startswith('/'):
|
||||
elif not isinstance(archive_dir_name, str):
|
||||
raise ValueError("prefix not a bytes object: %s" % repr(archive_dir_name))
|
||||
elif archive_dir_name.startswith('/'):
|
||||
raise VCSError("Prefix cannot start with leading slash")
|
||||
elif prefix.strip() == '':
|
||||
elif archive_dir_name.strip() == '':
|
||||
raise VCSError("Prefix cannot be empty")
|
||||
return prefix
|
||||
return archive_dir_name
|
||||
|
||||
@LazyProperty
|
||||
def root(self):
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
${_('Download full tree ZIP')}
|
||||
</a>
|
||||
% else:
|
||||
<a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id), _query={'at_path':c.f_path})}">
|
||||
<a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id), _query={'at_path':c.f_path, 'with_hash': '1'})}">
|
||||
${_('Download this tree ZIP')}
|
||||
</a>
|
||||
% endif
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@
|
|||
<div class="enabled pull-left" style="margin-right: 10px">
|
||||
|
||||
<div class="btn-group btn-group-actions">
|
||||
<a class="archive_link btn btn-small" data-ext=".zip" href="${h.route_path('repo_archivefile',repo_name=c.rhodecode_db_repo.repo_name, fname=c.rhodecode_db_repo.landing_ref_name+'.zip')}">
|
||||
<a class="archive_link btn btn-small" data-ext=".zip" href="${h.route_path('repo_archivefile',repo_name=c.rhodecode_db_repo.repo_name, fname=c.rhodecode_db_repo.landing_ref_name+'.zip', _query={'with_hash': '1'})}">
|
||||
<i class="icon-download"></i>
|
||||
${c.rhodecode_db_repo.landing_ref_name}.zip
|
||||
## replaced by some JS on select
|
||||
|
|
@ -202,8 +202,7 @@
|
|||
% for a_type, content_type, extension in h.ARCHIVE_SPECS:
|
||||
% if extension not in ['.zip']:
|
||||
<li>
|
||||
|
||||
<a class="archive_link" data-ext="${extension}" href="${h.route_path('repo_archivefile',repo_name=c.rhodecode_db_repo.repo_name, fname=c.rhodecode_db_repo.landing_ref_name+extension)}">
|
||||
<a class="archive_link" data-ext="${extension}" href="${h.route_path('repo_archivefile',repo_name=c.rhodecode_db_repo.repo_name, fname=c.rhodecode_db_repo.landing_ref_name+extension, _query={'with_hash': '1'})}">
|
||||
<i class="icon-download"></i>
|
||||
${c.rhodecode_db_repo.landing_ref_name+extension}
|
||||
</a>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue