diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 5a546386..3c42232d 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -29,6 +29,7 @@ # libraries here as they will become a requirement for all commands. import difflib +from typing import List import git import glob import io @@ -4300,7 +4301,7 @@ def get_app_display_name(app): return app.get('AutoName') or app['id'] -def local_rsync(options, fromdir, todir): +def local_rsync(options, fromdir, todir, args: List[str] = []): """Rsync method for local to local copying of things. This is an rsync wrapper with all the settings for safe use within @@ -4317,6 +4318,7 @@ def local_rsync(options, fromdir, todir): rsyncargs += ['--verbose'] if options.quiet: rsyncargs += ['--quiet'] + rsyncargs += args logging.debug(' '.join(rsyncargs + [fromdir, todir])) if subprocess.call(rsyncargs + [fromdir, todir]) != 0: raise FDroidException() diff --git a/fdroidserver/deploy.py b/fdroidserver/deploy.py index b668e2b0..4d581470 100644 --- a/fdroidserver/deploy.py +++ b/fdroidserver/deploy.py @@ -561,9 +561,11 @@ def sync_from_localcopy(repo_section, local_copy_dir): """ logging.info('Syncing from local_copy_dir to this repo.') if options.index_only: + rsyncargs = ['--include', "*/"] + _get_index_includes(repo_section) + ['--exclude', '*'] common.local_rsync(common.get_options(), _get_index_includes(local_copy_dir), - repo_section.rstrip('/') + '/') + repo_section.rstrip('/') + '/', + args=rsyncargs) else: # trailing slashes have a meaning in rsync which is not needed here, so # make sure both paths have exactly one trailing slash @@ -588,9 +590,11 @@ def update_localcopy(repo_section, local_copy_dir): """ if options.index_only: + rsyncargs = ['--include', "*/"] + _get_index_includes(repo_section) + ['--exclude', '*'] common.local_rsync(common.get_options(), _get_index_includes(repo_section), - repo_section.rstrip('/') + '/') + local_copy_dir, + args=rsyncargs) else: # local_copy_dir is guaranteed to have a trailing slash in main() below common.local_rsync(common.get_options(), repo_section, local_copy_dir) diff --git a/tests/deploy.TestCase b/tests/deploy.TestCase index 4c0c8535..41d40088 100755 --- a/tests/deploy.TestCase +++ b/tests/deploy.TestCase @@ -555,6 +555,66 @@ class DeployTest(unittest.TestCase): fdroidserver.deploy.update_serverwebroot(serverwebroot, repo_section) self.assertEqual(call_iteration, 1, 'expected 1 invocations of subprocess.call') + def test_update_localcopy_in_index_only_mode(self): + # setup parameters for this test run + fdroidserver.deploy.options.no_chcksum = False + fdroidserver.deploy.options.verbose = True + fdroidserver.deploy.options.quiet = False + fdroidserver.deploy.options.identity_file = None + fdroidserver.deploy.options.index_only = True + repo_section = 'repo' + + # setup function for asserting subprocess.call invocations + call_iteration = 0 + + with tempfile.TemporaryDirectory() as local_copy_dir: + def update_localcopy_call(cmd): + nonlocal call_iteration + if call_iteration == 0: + self.assertListEqual( + cmd, + [ + 'rsync', + '--recursive', '--safe-links', '--times', '--perms', + '--one-file-system', '--delete', '--chmod=Da+rx,Fa-x,a+r,u+w', + '--verbose', + '--include', + "*/", + '--include', + 'repo/entry.jar', + '--include', + 'repo/entry.json', + '--include', + 'repo/entry.json.asc', + '--include', + 'repo/index-v1.jar', + '--include', + 'repo/index-v1.json', + '--include', + 'repo/index-v1.json.asc', + '--include', + 'repo/index-v2.json', + '--include', + 'repo/index-v2.json.asc', + '--include', + 'repo/index.jar', + '--include', + 'repo/index.xml', + '--exclude', + "*", + 'repo', + local_copy_dir, + ], + ) + else: + self.fail('unexpected subprocess.call invocation') + call_iteration += 1 + return 0 + + with mock.patch('subprocess.call', side_effect=update_localcopy_call): + fdroidserver.deploy.update_localcopy(repo_section, local_copy_dir) + self.assertEqual(call_iteration, 1, 'expected 1 invocations of subprocess.call') + @unittest.skipIf( not os.getenv('VIRUSTOTAL_API_KEY'), 'VIRUSTOTAL_API_KEY is not set' )