summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scripts/.gitignore2
-rw-r--r--scripts/Makefile6
-rw-r--r--scripts/check-licenses.py425
-rwxr-xr-xscripts/check-licenses.py~34
-rwxr-xr-xscripts/check-licenses2.py~165
-rwxr-xr-xscripts/manifest.py6
-rw-r--r--scripts/tests/generate-mirror-commands/reference-mirror.sh (renamed from scripts/tests/reference-mirror.sh)0
7 files changed, 634 insertions, 4 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 927775a..179c022 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,2 +1,2 @@
__pycache__
-tests/mirror.sh
+tests/generate-mirror-commands/mirror.sh
diff --git a/scripts/Makefile b/scripts/Makefile
index 763d794..ad28c86 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -1,7 +1,7 @@
.PHONY: check
-check: tests/mirror.sh
- cmp $< tests/reference-mirror.sh
+check: tests/generate-mirror-commands/mirror.sh
+ cmp $< $(dir $<)reference-mirror.sh
-tests/mirror.sh: ../default.xml generate-mirror-commands.py
+tests/generate-mirror-commands/mirror.sh: ../default.xml generate-mirror-commands.py
./generate-mirror-commands.py $< > $@
diff --git a/scripts/check-licenses.py b/scripts/check-licenses.py
new file mode 100644
index 0000000..d70807e
--- /dev/null
+++ b/scripts/check-licenses.py
@@ -0,0 +1,425 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+import os
+import re
+import sh
+import sys
+
+import manifest
+
+debug = False
+print_headers = False
+verbose = False
+
+_data = {}
+
+def has_android_free_license_filename(data, repository_path):
+ details = {}
+ found = False
+ for filename in data.get('files', []):
+ path = repository_path + os.sep + filename
+
+ if os.path.exists(path):
+ details[path] = {}
+ details[path]['free_license'] = True
+ details[path]['type'] = 'license-filename'
+ if not found:
+ found = True
+ if not debug:
+ return True, details
+
+ return found, details
+
+_license_filenames = {
+ 'license-filename': {
+ 'func' : has_android_free_license_filename,
+ 'files' : [
+ 'MODULE_LICENSE_BSD_LIKE',
+ 'MODULE_LICENSE_APACHE2',
+ 'MODULE_LICENSE_BSD',
+ 'MODULE_LICENSE_MIT',
+ 'MODULE_LICENSE_BSD_APL2',
+ 'MODULE_LICENSE_GPL',
+ 'MODULE_LICENSE_PUBLIC_DOMAIN',
+ ],
+ 'sha1sums' : None,
+ },
+}
+_data.update(_license_filenames)
+
+#################
+# License files #
+#################
+license_files = [
+ 'COPYING',
+ 'LICENSE',
+ 'LICENCE',
+ 'NIST-CONDITIONS-OF-USE',
+]
+
+stock_license_files_checksums = [
+ ##############
+ # Apache 2.0 #
+ ##############
+ '11d8a409876496183c8fba90eb70f25301875b67',
+ '5a7d7df655ba40478fae80a6abafc6afc36f9b6a',
+ '82f88802986ad28deac953dc06bd0bb52f3d012c',
+ '04f15afbbe53b69d0e4870e9308efae75efa773a',
+ '58853eb8199b5afe72a73a25fd8cf8c94285174b',
+ #########
+ # Boost #
+ #########
+ #external/catch2/LICENSE
+ '3cba29011be2b9d59f6204d6fa0a386b1b2dbd90',
+ #######
+ # BSD #
+ #######
+ # external/openssh/LICENCE, also contains
+ # various other permissive licenses
+ '0ea904438c8997ec028278e2d51a0af60ef7e698',
+ # external/angle/LICENSE
+ '37126a0eda0b30f44070f59e6833187e99a7eb83',
+ #################
+ # BSD 2 clauses #
+ #################
+ # external/bc/LICENSE
+ 'e340c40163eac1621be590383a187e06a55f7a46',
+ # external/neon_2_sse/LICENSE
+ '431443c5e39f2a2f7514b387082e5ac2877923bd',
+ ###########################################################################
+ # BSD 2 clauses + Apache2 + MIT/Expat + other weak free software licenses #
+ ###########################################################################
+ # prebuilts/maven_repo/bumptech/LICENSE
+ '1101898f21325ac882951894f17493b08925749a',
+ #################
+ # BSD 3 clauses #
+ #################
+ # prebuilts/go/linux-x86/LICENSE
+ 'd6a5f1ecaedd723c325a2063375b3517e808a2b5',
+ # external/capstone/LICENSE
+ '861af24907e399e873920dbbff1ea1dd73a9ba35',
+ # external/toolchain-utils/LICENSE
+ 'd9005d5cecc3c5eaa7afef623b99eb38b5cdf6ac',
+ # external/libsrtp2/LICENSE
+ 'e8a22b77b707f4d8fc8cb2f86c117fd8f7251635',
+ # ChromeOS authors
+ # external/crosvm/LICENSE, external/puffin/LICENSE
+ '1f0a15bbb0febb59ac19144ac84f6562770372ef',
+ # external/vixl/LICENCE
+ '94836c813237bec24a2b695dce00f85cad7cb3a5',
+ # modifications: "The Go Authors" + year
+ # external/golang-protobuf/LICENSE
+ 'aa9b240f558caed367795f667629ccbca28f20b2',
+ # external/libyuv/LICENSE
+ 'e9acea9922263c04ea4c231e258b25e6898ec932',
+ ###########################
+ # BSD 3 clauses + unicode #
+ ###########################
+ # external/google-breakpad/LICENSE
+ '86dabb511ec367808a04ba4b87c4a3e0b97765e2',
+
+ ###############
+ # Expat / MIT #
+ ###############
+ # external/libepoxy/COPYING
+ '00f34512740377ad1f155eaa15936e472661c5e3',
+ # prebuilts/ktlint/LICENSE
+ 'da2a23609257d3856b866a33d337884785513c71',
+ # external/python/six/LICENSE
+ '5a09fe8ab2f714dc1fa204fc261eceb8d82962e8',
+ # external/googletest/LICENSE
+ '5a2314153eadadc69258a9429104cd11804ea304',
+ # external/fonttools/LICENSE
+ '3b4f969a237019242665f7adacc882c35a82c145',
+ # external/robolectric-shadows/LICENSE
+ '14e5e69109cfb70093b929e7191b6dab02b37c51',
+ ########
+ # GPL2 #
+ ########
+ # external/ethtool/COPYING
+ '4cc77b90af91e615a64ae04893fdffa7939db84c',
+ # external/oj-libjdwp/LICENSE
+ 'a4fb972c240d89131ee9e16b845cd302e0ecb05f',
+ ##############
+ # GPLv2 only #
+ ##############
+ # external/autotest/LICENSE
+ '86f2601747ba9f6ab13cf7eabfdfe720416965bb',
+ ##########################################
+ # GPLv2 + GPLv2||LGPL 2.1 for some parts #
+ ##########################################
+ # external/f2fs-tools/COPYING
+ 'a55afe19b58d728b586547acb09862752d4f1b76',
+ # external/libusb/COPYING
+ 'caeb68c46fa36651acf592771d09de7937926bb3',
+ # external/libfuse/LICENSE
+ '0028a619acd3ff14a6d35b2837bb85a3ad2bab2b',
+ ###############
+ # Imagemagick #
+ ###############
+ # external/ImageMagick/LICENSE
+ '1de15ef06b3465e1bb922ba9c69a2a67a0263455',
+ ###################
+ # LGPL || Apache2 #
+ ###################
+ # external/javaparser/LICENSE
+ 'caaf43ae64cd4674b8e99869d658870b65fd6733',
+ ########################
+ # MPLv2 + 2 clause BSD #
+ ########################
+ # "libkms++ is mostly under the MPLv2 license except for a snippet in
+ # modedb_cea.cpp which is derived from 2-clause BSD licensed files from the
+ # Linux kernel."
+ # external/libkmsxx/LICENSE
+ 'a4ac2bea4ed2d4726528801b8880415b70f26157',
+ #####################################################
+ # (MPLv2 || GPLv2 || LGPLv2.1) +? ||? BSD 3 clauses #
+ #####################################################
+ # external/chromium-libpac/LICENSE
+ '437ba59383a90fd0033eb7b77370eb6c399b72de',
+ ###########
+ # OFL-1.1 #
+ ###########
+ # TODO: The OFL licenses are almost all the same with some variations at the
+ # very begining with the font name and some minor variations, so it could be
+ # automatically detected with code to make the maintenance easier when
+ # porting Replicant to newer Android versions
+ # external/google-fonts/source-sans-pro/LICENSE
+ 'a55d8584dd1af1bd63bf607a6195d56beb8ee564',
+ # external/google-fonts/lato/LICENSE
+ '76897b37e127e2332a1a79aab2e0d6f30ccdc47a',
+ # external/google-fonts/arvo/LICENSE
+ '2ef38678dab952ed745c71e59e9a2f595cddb0f4',
+ # external/google-fonts/big-shoulders-text/LICENSE
+ '35765f09b7708df97741f83ca94978a8a742adfa',
+ # external/google-fonts/fraunces/LICENSE
+ '587180e421d550a5e4bf6a6e76275c21d486e8ef',
+ # external/google-fonts/arbutus-slab/LICENSE
+ 'd9c9ee6d894d5fd114fb317a2fda29823dd90d57',
+ # external/google-fonts/barlow/LICENSE
+ '92050ce5096f0a97a4140e5be847f25901d1f327',
+ # external/google-fonts/karla/LICENSE
+ '0c63ce44ac335ff9fab43f701affbb85475d9dda',
+ # external/google-fonts/lustria/LICENSE
+ '5d0d72fede5a8ae33cb8f75ae2c9814092ad19b2',
+ # external/google-fonts/rubik/LICENSE
+ 'bf47091f200e5c46fa3032c8a143bb197f2f6a22',
+ # external/google-fonts/zilla-slab/LICENSE
+ 'e81354927f121d3ba67ef5e48b34dc930cdeca06',
+ #########
+ # PSF 2 #
+ #########
+ # external/python/ipaddress/LICENSE
+ '3f92966b8a60875dca8d9e1d6b63ac7eb9e4178e',
+ ##############
+ # Python 2.1 #
+ ##############
+ '0c492b235e749a739628cdd18d8c860c6f70396b',
+ # external/python/cpython2/LICENSE
+ 'ee7904173585b2506078dc8dac150638f1b3e537',
+ # external/python/cpython3/LICENSE
+ 'f8ec80e0c4f67f0f460f6933dcbe99f36a82f023',
+ ##########################
+ # Unlicense || Expat/MIT #
+ ##########################
+ # external/rust/crates/byteorder/COPYING
+ 'dd445710e6e4caccc4f8a587a130eaeebe83f6f6',
+
+ #######
+ # X11 #
+ #######
+ # external/shaderc/spirv-headers/LICENSE
+ '9a84200f47e09abfbde1a6b25028460451b23d03',
+]
+
+modified_license_files_checksums = [
+ ##############
+ # Apache 2.0 #
+ ##############
+ '11d8a409876496183c8fba90eb70f25301875b67',
+ # packages/apps/Dialer/LICENSE
+ # Has additional apache 2005-2008 copyright header
+ 'b3ca008f1479a18a234094ea7169bc2dbbd141bb',
+ # hardware/st/secure_element/LICENSE
+ '5166166f89e06525e7cddb92f37f8670b3bd628f',
+ # external/subsampling-scale-image-view/LICENSE
+ '8a16eeaa6a87c42f0d7346e1f641d060bbf1f27f',
+ #########
+ # GPLv2 #
+ #########
+ # libcore/LICENSE
+ '56423feb073860b0b2de8dd6dc9053c2e291f483',
+ #############
+ # LGPLv 2.1 #
+ #############
+ # prebuilts/checkstyle/LICENSE
+ 'afb804cc9151ceb4044111bd37da309b29e844f3',
+ # external/kmod/COPYING
+ 'f0a5efd7fe620e424bc7f8dcf809f2166ae4f372',
+ # external/libexif/COPYING
+ 'e8b46065a76eacf8b16ba95038a8dadf61dcc264',
+ # external/libnl/COPYING
+ 'acd27bde2d7451c37a297c578899e29794a3008d',
+ # external/libiio/LICENSE
+ 'adfb290d0f03d365c548d0834d3276a96665b76c',
+
+]
+
+def has_stock_free_license_file(data, repository_path):
+ details = {}
+ found = False
+
+ for filename in data.get('files', []):
+ path = repository_path + os.sep + filename
+
+ if os.path.exists(path):
+ sha1sum = sh.sha1sum(path).split(' ')[0]
+
+ new_found = sha1sum in data.get('sha1sums', [])
+
+ details[path] = {}
+ details[path]['free_license'] = new_found
+ details[path]['sha1sum'] = sha1sum
+ details[path]['type'] = 'stock-license-file'
+
+ if not found:
+ found = new_found
+ if not debug:
+ return found, details
+
+ return found, details
+
+stock_license_files = {
+ 'stock-license-file': {
+ 'func' : has_stock_free_license_file,
+ 'files': license_files,
+ 'sha1sums': stock_license_files_checksums,
+ },
+}
+_data.update(stock_license_files)
+
+def has_modified_free_license_file(data, repository_path):
+ details = {}
+ found = False
+
+ for filename in data.get('files', []):
+ path = repository_path + os.sep + filename
+
+ if os.path.exists(path):
+ # Remove all whitespaces and line breaks
+ buf = open(path, 'r').read()
+ buf = buf.replace(' ', '')
+ buf = buf.replace('\r', '')
+ buf = buf.replace('\n', '')
+
+ sha1sum = sh.sha1sum(_in=buf).split(' ')[0]
+
+ new_found = sha1sum in data.get('sha1sums', [])
+
+ details[path] = {}
+ details[path]['free_license'] = new_found
+ details[path]['sha1sum'] = sha1sum
+ details[path]['type'] = 'modified-license-file'
+
+ if not found:
+ found = new_found
+ if not debug:
+ return found, details
+
+ return found, details
+
+modified_license_files = {
+ 'modified-license-file': {
+ 'func' : has_modified_free_license_file,
+ 'files': license_files,
+ 'sha1sums': modified_license_files_checksums,
+ },
+}
+
+_data.update(modified_license_files)
+
+def has_free_license(data, repository_path):
+ found = False
+ details = []
+
+ for method, method_data in data.items():
+ new_found, new_details = method_data['func'](data[method], repository_path)
+ details.append(new_details)
+
+ if not found:
+ found = new_found
+ if not debug and found:
+ return found, details
+
+ return found, details
+
+def print_todo(repository_path, details):
+ stock_licenses_sha1sum = None
+ modified_licenses_sha1sum = None
+ license_file_path = None
+ for data in details:
+ if len(data) == 0:
+ continue
+ for file_path, values in data.items():
+ if values['type'] == 'stock-license-file':
+ stock_licenses_sha1sum = values['sha1sum']
+ if license_file_path == None:
+ license_file_path = file_path
+ else:
+ assert(license_file_path == file_path)
+ elif values['type'] == 'modified-license-file':
+ modified_licenses_sha1sum = values['sha1sum']
+ if license_file_path == None:
+ license_file_path = file_path
+ else:
+ assert(license_file_path == file_path)
+
+ if license_file_path \
+ and stock_licenses_sha1sum \
+ and modified_licenses_sha1sum:
+ if print_headers:
+ print("| {} | {} | {} |".format("path", "file sha1sum",
+ "stripped file sha1sum"))
+ print("| {} | {} | {} |".format(license_file_path,
+ stock_licenses_sha1sum,
+ modified_licenses_sha1sum))
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ usage(sys.argv[0])
+
+ manifest_xml_path = sys.argv[1]
+
+ m = manifest.Manifest(manifest_xml_path)
+ paths = m.list_repositories_paths()
+
+ nr_unknown_repositories = len(paths)
+ for path in paths:
+ if verbose:
+ print(path)
+ found, details = has_free_license(_data, path)
+ if found:
+ nr_unknown_repositories -= 1
+ if verbose:
+ print(found, details)
+ print()
+ if not found and len(details) > 0:
+ print_todo(path, details)
+
+ print("Remaining: {} done: {} total: {}".format(
+ nr_unknown_repositories,
+ len(paths) - nr_unknown_repositories,
+ len(paths)))
diff --git a/scripts/check-licenses.py~ b/scripts/check-licenses.py~
new file mode 100755
index 0000000..f3f022c
--- /dev/null
+++ b/scripts/check-licenses.py~
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+import sys
+
+import manifest
+
+def usage(progname):
+ print ('Usage:')
+ print ('\t{} <path/to/default.xml>'.format(progname))
+ sys.exit(1)
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ usage(sys.argv[0])
+
+ manifest_xml_path = sys.argv[1]
+
+ m = manifest.Manifest(manifest_xml_path)
+ m.parse()
+ m.close()
diff --git a/scripts/check-licenses2.py~ b/scripts/check-licenses2.py~
new file mode 100755
index 0000000..f1973f4
--- /dev/null
+++ b/scripts/check-licenses2.py~
@@ -0,0 +1,165 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+_data = {}
+
+def has_android_free_license_filename(data, repository_path):
+ pass
+
+_license_filenames = {
+ 'license-filename': {
+ 'func' : has_android_free_license_filename,
+ 'files' : [
+ 'MODULE_LICENSE_BSD_LIKE',
+ 'MODULE_LICENSE_APACHE2',
+ 'MODULE_LICENSE_BSD',
+ 'MODULE_LICENSE_MIT',
+ 'MODULE_LICENSE_BSD_APL2',
+ 'MODULE_LICENSE_GPL',
+ 'MODULE_LICENSE_PUBLIC_DOMAIN',
+ ],
+ 'sha1sums' : None,
+ },
+}
+_data.update(_license_filenames)
+
+#################
+# License files #
+#################
+license_files = [
+ 'COPYING',
+ 'LICENSE',
+ 'LICENCE',
+ 'NIST-CONDITIONS-OF-USE',
+]
+
+stock_license_files_checksums = [
+ ##############
+ # Apache 2.0 #
+ ##############
+ '11d8a409876496183c8fba90eb70f25301875b67',
+ '5a7d7df655ba40478fae80a6abafc6afc36f9b6a',
+ '82f88802986ad28deac953dc06bd0bb52f3d012c',
+ '04f15afbbe53b69d0e4870e9308efae75efa773a',
+ '58853eb8199b5afe72a73a25fd8cf8c94285174b',
+ #######
+ # BSD #
+ #######
+ # external/openssh/LICENCE, also contains
+ # various other permissive licenses
+ '0ea904438c8997ec028278e2d51a0af60ef7e698',
+ ###############
+ # Expat / MIT #
+ ###############
+ # external/libepoxy/COPYING
+ '00f34512740377ad1f155eaa15936e472661c5e3',
+ ###########
+ # OFL-1.1 #
+ ###########
+ # external/google-fonts/source-sans-pro/LICENSE
+ 'a55d8584dd1af1bd63bf607a6195d56beb8ee564',
+ # external/google-fonts/lato/LICENSE
+ '76897b37e127e2332a1a79aab2e0d6f30ccdc47a',
+ # external/google-fonts/arvo/LICENSE
+ '2ef38678dab952ed745c71e59e9a2f595cddb0f4',
+ # external/google-fonts/big-shoulders-text/LICENSE
+ '35765f09b7708df97741f83ca94978a8a742adfa',
+ # external/google-fonts/fraunces/LICENSE
+ '587180e421d550a5e4bf6a6e76275c21d486e8ef',
+ ##############
+ # Python 2.1 #
+ ##############
+ '0c492b235e749a739628cdd18d8c860c6f70396b',
+]
+
+modified_license_files_checksums = [
+ # Apache 2.0
+ '11d8a409876496183c8fba90eb70f25301875b67',
+]
+
+def has_stock_free_license_file(path):
+ pass
+
+stock_license_files = {
+ 'stock-license-file': {
+ 'func' : has_stock_free_license_file,
+ 'files': license_files,
+ 'sha1sums': stock_license_files_checksums,
+ },
+}
+_data.update(stock_license_files)
+
+def has_modified_free_license_file(path):
+ pass
+
+modified_license_files = {
+ 'modified-license-file': {
+ 'func' : has_modified_free_license_file,
+ 'files': license_files,
+ 'sha1sums': modified_license_files_checksums,
+ },
+}
+
+_data.update(modified_license_files)
+
+
+if __name__ == '__main__':
+ verbose = True
+ if len(sys.argv) != 2:
+ usage(sys.argv[0])
+
+ manifest_xml_path = sys.argv[1]
+
+ m = manifest.Manifest(manifest_xml_path)
+ paths = m.list_repositories_paths()
+
+ nr_unknown_repositories = 0
+ nr_unknown_licenses = 0
+ for path in paths:
+ l = RepositoryLicense(path)
+ found, details = l.has_free_license()
+ if not found and verbose:
+ nr_unknown_repositories += 1
+ if len(details) > 0:
+ for k, v in details.items():
+ printed_header = False
+ if v['type'] in ['stock-license-file',
+ 'modified-license-file']:
+ if not printed_header:
+ print("{}:".format(path))
+ printed_header = True
+ print("- {} {}".format(k, v['sha1sum']))
+ nr_unknown_licenses += 1
+ # We'll handle repositories with READMEs when we
+ # will have handled all the licenses files
+ # else:
+ # print("- TODO: look at the READMEs")
+ # We'll handle these repositories when we
+ # will have handled all the licenses files
+ # else:
+ # print("{}".format(path))
+
+ if verbose:
+ if nr_unknown_repositories > 0 or nr_unknown_licenses > 0:
+ print()
+ print("Total:")
+ print("------")
+ if nr_unknown_repositories > 0:
+ print("- {} repositories to check".format(nr_unknown_repositories))
+ if nr_unknown_licenses > 0:
+ print("- {} licenses to check".format(nr_unknown_licenses))
+
+
diff --git a/scripts/manifest.py b/scripts/manifest.py
index d1188e6..065ee7f 100755
--- a/scripts/manifest.py
+++ b/scripts/manifest.py
@@ -184,5 +184,11 @@ class Manifest(object):
print(command)
print('')
+ def list_repositories_paths(self):
+ paths = []
+ for child in self.root.iter('project'):
+ paths.append(self.get_project_property(child, 'path'))
+ return paths
+
def close(self):
self.xml_file.close()
diff --git a/scripts/tests/reference-mirror.sh b/scripts/tests/generate-mirror-commands/reference-mirror.sh
index 7d9ed43..7d9ed43 100644
--- a/scripts/tests/reference-mirror.sh
+++ b/scripts/tests/generate-mirror-commands/reference-mirror.sh