Merge branch 'remove-RepoType-bzr-support' into 'master'

purge support for deprecated RepoType: bzr svn

See merge request fdroid/fdroidserver!1783
This commit is contained in:
Hans-Christoph Steiner
2026-03-05 19:05:55 +00:00
8 changed files with 63 additions and 68 deletions

View File

@@ -616,7 +616,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext
tarball = tarfile.open(os.path.join(tmp_dir, tarname), "w:gz")
def tarexc(t):
return None if any(t.name.endswith(s) for s in ['.svn', '.git', '.hg', '.bzr']) else t
return None if any(t.name.endswith(s) for s in ['.git', '.hg']) else t
tarball.add(build_dir, tarname, filter=tarexc)
tarball.close()

View File

@@ -152,7 +152,7 @@ def check_tags(app: metadata.App, pattern: str) -> tuple[str, int, str]:
else:
repotype = app.RepoType
if repotype not in ('git', 'git-svn', 'hg', 'bzr'):
if repotype not in ('git', 'git-svn', 'hg'):
raise MetaDataException(_('Tags update mode only works for git, hg, bzr and git-svn repositories currently'))
if repotype == 'git-svn' and ';' not in app.Repo:
@@ -315,8 +315,6 @@ def check_repomanifest(app: metadata.App, branch: Optional[str] = None) -> tuple
vcs.gotorevision(branch)
elif repotype == 'hg':
vcs.gotorevision(branch)
elif repotype == 'bzr':
vcs.gotorevision(None)
last_build = get_last_build_from_app(app)
try_init_submodules(app, last_build, vcs)

View File

@@ -1546,14 +1546,10 @@ def getvcs(vcstype, remote, local):
return vcs_gitsvn(remote, local)
if vcstype == 'hg':
return vcs_hg(remote, local)
if vcstype == 'bzr':
return vcs_bzr(remote, local)
if vcstype == 'srclib':
if str(local) != os.path.join('build', 'srclib', str(remote)):
raise VCSException("Error: srclib paths are hard-coded!")
return getsrclib(remote, os.path.join('build', 'srclib'), raw=True)
if vcstype == 'svn':
raise VCSException("Deprecated vcs type 'svn' - please use 'git-svn' instead")
raise VCSException("Invalid vcs type " + vcstype)
@@ -1565,17 +1561,6 @@ def getsrclibvcs(name):
class vcs:
def __init__(self, remote, local):
# svn, git-svn and bzr may require auth
self.username = None
if self.repotype() in ('git-svn', 'bzr'):
if '@' in remote:
if self.repotype == 'git-svn':
raise VCSException("Authentication is not supported for git-svn")
self.username, remote = remote.split('@')
if ':' not in self.username:
raise VCSException(_("Password required with username"))
self.username, self.password = self.username.split(':')
self.remote = remote
self.local = local
self.clone_failed = False
@@ -1874,6 +1859,10 @@ class vcs_git(vcs):
class vcs_gitsvn(vcs):
def __init__(self, remote, local):
if '@' in remote:
raise VCSException("Authentication is not supported for git-svn")
super().__init__(remote, local)
def repotype(self):
return 'git-svn'
@@ -2082,48 +2071,6 @@ class vcs_hg(vcs):
def _gettags(self):
p = FDroidPopen(['hg', 'tags', '-q'], cwd=self.local, output=False)
return p.output.splitlines()[1:]
class vcs_bzr(vcs):
def repotype(self):
return 'bzr'
def clientversioncmd(self):
return ['bzr', '--version']
def bzr(self, args, envs=dict(), cwd=None, output=True):
"""Prevent bzr from ever using SSH to avoid security vulns."""
envs.update({
'BZR_SSH': 'false',
})
return FDroidPopen(['bzr', ] + args, envs=envs, cwd=cwd, output=output)
def gotorevisionx(self, rev):
if not os.path.exists(self.local):
p = self.bzr(['branch', self.remote, str(self.local)], output=False)
if p.returncode != 0:
self.clone_failed = True
raise VCSException("Bzr branch failed", p.output)
else:
p = self.bzr(['clean-tree', '--force', '--unknown', '--ignored'], cwd=self.local, output=False)
if p.returncode != 0:
raise VCSException("Bzr revert failed", p.output)
if not self.refreshed:
p = self.bzr(['pull'], cwd=self.local, output=False)
if p.returncode != 0:
raise VCSException("Bzr update failed", p.output)
self.refreshed = True
revargs = list(['-r', rev] if rev else [])
p = self.bzr(['revert'] + revargs, cwd=self.local, output=False)
if p.returncode != 0:
raise VCSException("Bzr revert of '%s' failed" % rev, p.output)
def _gettags(self):
p = self.bzr(['tags'], cwd=self.local, output=False)
return [tag.split(' ')[0].strip() for tag in
p.output.splitlines()]
# fmt: on

View File

@@ -49,11 +49,7 @@ def make_source_tarball(app, build, output_dir=pathlib.Path('unsigned')):
tarball = tarfile.open(os.path.join(output_dir, tarname), "w:gz")
def tarexc(t):
return (
None
if any(t.name.endswith(s) for s in ['.svn', '.git', '.hg', '.bzr'])
else t
)
return None if any(t.name.endswith(s) for s in ['.git', '.hg']) else t
tarball.add(build_dir, tarname, filter=tarexc)
tarball.close()

View File

@@ -433,7 +433,7 @@ valuetypes = {
["Litecoin"]),
FieldValidator("Repo Type",
r'^(git|git-svn|svn|hg|bzr|srclib)$',
r'^(git|git-svn|hg|srclib)$',
["RepoType"]),
FieldValidator("Binaries",

View File

@@ -947,7 +947,7 @@ def scan_source(build_dir, build=metadata.Build(), json_per_build=None):
# Iterate through all files in the source code
for root, dirs, files in os.walk(build_dir, topdown=True):
# It's topdown, so checking the basename is enough
for ignoredir in ('.hg', '.git', '.svn', '.bzr'):
for ignoredir in ('.hg', '.git'):
if ignoredir in dirs:
dirs.remove(ignoredir)

View File

@@ -449,6 +449,12 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase):
vcs1 = fdroidserver.common.getvcs('git', git_url, gitrepo)
vcs1.gotorevision('0.3', refresh=False)
def test_getvcs_svn_auth_error(self):
with self.assertRaises(VCSException):
fdroidserver.common.getvcs(
'git-svn', 'https://user@svn.code.sf.net/p/foo/code/trunk', self.testdir
)
def test_setup_vcs_srclib(self):
app = fdroidserver.metadata.App(
{

View File

@@ -1865,6 +1865,54 @@ class MetadataTest(unittest.TestCase):
},
)
def test_read_srclibs_with_unknown_RepoType(self):
"""Ensure everything parses when support for a RepoType is removed.
metadata files must use an active RepoType: but srclibs only
need to use an active RepoType: if they are being actively used,
e.g. `fdroid build`. This makes it easier to deprecate RepoTypes.
"""
os.chdir(self.testdir)
srclib = 'unsupported'
sf = Path(f'srclibs/{srclib}.yml')
sf.parent.mkdir()
sf.write_text(
textwrap.dedent(
f'''
RepoType: {srclib}
Repo: foo://foo.host/repo
'''
)
)
appid = 'com.example'
mf = Path(f'metadata/{appid}.yml')
mf.parent.mkdir()
mf.write_text(
textwrap.dedent(
f'''
Builds:
- versionCode: 1
srclibs: {srclib}
'''
)
)
fdroidserver.metadata.srclibs = None
apps = fdroidserver.metadata.read_metadata()
self.assertEqual(apps[appid]['Builds'][0]['srclibs'], [srclib])
self.assertDictEqual(
fdroidserver.metadata.srclibs,
{
srclib: {
'RepoType': srclib,
'Repo': 'foo://foo.host/repo',
'Prepare': None,
'Subdir': None,
},
},
)
def test_build_ndk_path(self):
with tempfile.TemporaryDirectory(prefix='android-sdk-') as sdk_path:
config = {'ndk_paths': {}, 'sdk_path': sdk_path}