From ddfbd1cc47f58deed4a5b4844f9850e2df5f4d26 Mon Sep 17 00:00:00 2001 From: relan Date: Thu, 21 May 2020 08:50:08 +0300 Subject: [PATCH 1/3] build: fix directories removal The 'dirs' array contains a single-level listing of a directory, e. g. ['app', 'build', 'build.gradle', 'gradle', '.gradle']. Multi-component paths like 'build/tmp' could never be found in this array and thus were never removed. Call shutil.rmtree() without checking that the argument is in 'dirs'. If it exists and is a directory, it'll be removed. Otherwise shutil.rmtree() will do nothing. --- fdroidserver/build.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 41467533..df74cdba 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -475,8 +475,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext def del_dirs(dl): for d in dl: - if d in dirs: - shutil.rmtree(os.path.join(root, d)) + shutil.rmtree(os.path.join(root, d), ignore_errors=True) def del_files(fl): for f in fl: From 9ff77cfd1a83d7e253e3bd7cb7517d548b8993c8 Mon Sep 17 00:00:00 2001 From: relan Date: Thu, 21 May 2020 08:50:35 +0300 Subject: [PATCH 2/3] build: clean buildSrc/build The buildSrc directory contains custom build logic written in Kotlin. Before this change we had to 'scandelete' buildSrc/build in the build recipes becase 'gradle clean' leaves binary artifacts there. --- fdroidserver/build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index df74cdba..6d8e0241 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -493,6 +493,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext os.path.join('build', 'outputs'), os.path.join('build', 'reports'), os.path.join('build', 'tmp'), + os.path.join('buildSrc', 'build'), '.gradle']) del_files(['gradlew', 'gradlew.bat']) From 5b9944fcde698d4be78f767368f3f87ab7340558 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 26 May 2020 09:48:55 +0200 Subject: [PATCH 3/3] add test for things `fdroid build` cleans This needs a lot of mocking because build.build_local() is a gianormous single function. --- tests/build.TestCase | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/tests/build.TestCase b/tests/build.TestCase index 6b872ebb..547c0b6e 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -10,7 +10,9 @@ import re import shutil import sys import tempfile +import textwrap import unittest +from unittest import mock localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) @@ -121,6 +123,79 @@ class BuildTest(unittest.TestCase): self.assertEqual(versionCode, vc) self.assertEqual(versionName, vn) + def test_build_local_clean(self): + """Test if `fdroid build` cleans ant and gradle build products""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.build.options = mock.Mock() + fdroidserver.build.options.json = False + fdroidserver.build.options.notarball = True + fdroidserver.build.options.skipscan = False + + app = fdroidserver.metadata.App() + app.id = 'mocked.app.id' + build = fdroidserver.metadata.Build() + build.commit = '1.0' + build.output = app.id + '.apk' + build.scanignore = ['baz.so'] + build.versionCode = '1' + build.versionName = '1.0' + vcs = mock.Mock() + + os.mkdir('reports') + os.mkdir('target') + + for f in ('baz.so', 'foo.aar', 'gradle-wrapper.jar'): + with open(f, 'w') as fp: + fp.write('placeholder') + self.assertTrue(os.path.exists(f)) + + os.mkdir('build') + os.mkdir('build/reports') + with open('build.gradle', 'w') as fp: + fp.write('// placeholder') + + os.mkdir('bin') + os.mkdir('gen') + with open('build.xml', 'w') as fp: + fp.write(textwrap.dedent( + """ + + + + """)) + + def make_fake_apk(output, build): + with open(build.output, 'w') as fp: + fp.write('APK PLACEHOLDER') + return output + + with mock.patch('fdroidserver.common.replace_build_vars', wraps=make_fake_apk): + with mock.patch('fdroidserver.common.get_native_code', return_value='x86'): + with mock.patch('fdroidserver.common.get_apk_id', + return_value=(app.id, build.versionCode, build.versionName)): + with mock.patch('fdroidserver.common.is_apk_and_debuggable', return_value=False): + fdroidserver.build.build_local( + app, build, vcs, + build_dir=testdir, output_dir=testdir, + log_dir=None, srclib_dir=None, extlib_dir=None, tmp_dir=None, + force=False, onserver=False, refresh=False + ) + + self.assertTrue(os.path.exists('baz.so')) + self.assertTrue(os.path.exists('foo.aar')) + self.assertTrue(os.path.isdir('build')) + self.assertTrue(os.path.isdir('reports')) + self.assertTrue(os.path.isdir('target')) + self.assertFalse(os.path.exists('bin')) + self.assertFalse(os.path.exists('build/reports')) + self.assertFalse(os.path.exists('gen')) + self.assertFalse(os.path.exists('gradle-wrapper.jar')) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__))