diff options
| -rw-r--r-- | git_superproject.py | 100 | ||||
| -rw-r--r-- | subcmds/sync.py | 81 | ||||
| -rw-r--r-- | tests/test_git_superproject.py | 89 |
3 files changed, 212 insertions, 58 deletions
diff --git a/git_superproject.py b/git_superproject.py index e2045cfd..465d1f87 100644 --- a/git_superproject.py +++ b/git_superproject.py | |||
| @@ -25,8 +25,9 @@ Examples: | |||
| 25 | import os | 25 | import os |
| 26 | import sys | 26 | import sys |
| 27 | 27 | ||
| 28 | from error import GitError | 28 | from error import BUG_REPORT_URL, GitError |
| 29 | from git_command import GitCommand | 29 | from git_command import GitCommand |
| 30 | import platform_utils | ||
| 30 | 31 | ||
| 31 | 32 | ||
| 32 | class Superproject(object): | 33 | class Superproject(object): |
| @@ -46,6 +47,9 @@ class Superproject(object): | |||
| 46 | self._repodir = os.path.abspath(repodir) | 47 | self._repodir = os.path.abspath(repodir) |
| 47 | self._superproject_dir = superproject_dir | 48 | self._superproject_dir = superproject_dir |
| 48 | self._superproject_path = os.path.join(self._repodir, superproject_dir) | 49 | self._superproject_path = os.path.join(self._repodir, superproject_dir) |
| 50 | self._manifest_path = os.path.join(self._superproject_path, | ||
| 51 | 'superproject_override.xml') | ||
| 52 | self._work_git = os.path.join(self._superproject_path, 'superproject') | ||
| 49 | 53 | ||
| 50 | @property | 54 | @property |
| 51 | def project_shas(self): | 55 | def project_shas(self): |
| @@ -57,7 +61,7 @@ class Superproject(object): | |||
| 57 | 61 | ||
| 58 | Args: | 62 | Args: |
| 59 | url: superproject's url to be passed to git clone. | 63 | url: superproject's url to be passed to git clone. |
| 60 | branch: the branchname to be passed as argument to git clone. | 64 | branch: The branchname to be passed as argument to git clone. |
| 61 | 65 | ||
| 62 | Returns: | 66 | Returns: |
| 63 | True if 'git clone <url> <branch>' is successful, or False. | 67 | True if 'git clone <url> <branch>' is successful, or False. |
| @@ -86,13 +90,12 @@ class Superproject(object): | |||
| 86 | Returns: | 90 | Returns: |
| 87 | True if 'git pull <branch>' is successful, or False. | 91 | True if 'git pull <branch>' is successful, or False. |
| 88 | """ | 92 | """ |
| 89 | git_dir = os.path.join(self._superproject_path, 'superproject') | 93 | if not os.path.exists(self._work_git): |
| 90 | if not os.path.exists(git_dir): | 94 | raise GitError('git pull missing drectory: %s' % self._work_git) |
| 91 | raise GitError('git pull. Missing drectory: %s' % git_dir) | ||
| 92 | cmd = ['pull'] | 95 | cmd = ['pull'] |
| 93 | p = GitCommand(None, | 96 | p = GitCommand(None, |
| 94 | cmd, | 97 | cmd, |
| 95 | cwd=git_dir, | 98 | cwd=self._work_git, |
| 96 | capture_stdout=True, | 99 | capture_stdout=True, |
| 97 | capture_stderr=True) | 100 | capture_stderr=True) |
| 98 | retval = p.Wait() | 101 | retval = p.Wait() |
| @@ -110,14 +113,13 @@ class Superproject(object): | |||
| 110 | Returns: | 113 | Returns: |
| 111 | data: data returned from 'git ls-tree -r HEAD' instead of None. | 114 | data: data returned from 'git ls-tree -r HEAD' instead of None. |
| 112 | """ | 115 | """ |
| 113 | git_dir = os.path.join(self._superproject_path, 'superproject') | 116 | if not os.path.exists(self._work_git): |
| 114 | if not os.path.exists(git_dir): | 117 | raise GitError('git ls-tree. Missing drectory: %s' % self._work_git) |
| 115 | raise GitError('git ls-tree. Missing drectory: %s' % git_dir) | ||
| 116 | data = None | 118 | data = None |
| 117 | cmd = ['ls-tree', '-z', '-r', 'HEAD'] | 119 | cmd = ['ls-tree', '-z', '-r', 'HEAD'] |
| 118 | p = GitCommand(None, | 120 | p = GitCommand(None, |
| 119 | cmd, | 121 | cmd, |
| 120 | cwd=git_dir, | 122 | cwd=self._work_git, |
| 121 | capture_stdout=True, | 123 | capture_stdout=True, |
| 122 | capture_stderr=True) | 124 | capture_stderr=True) |
| 123 | retval = p.Wait() | 125 | retval = p.Wait() |
| @@ -130,22 +132,26 @@ class Superproject(object): | |||
| 130 | retval, p.stderr), file=sys.stderr) | 132 | retval, p.stderr), file=sys.stderr) |
| 131 | return data | 133 | return data |
| 132 | 134 | ||
| 133 | def GetAllProjectsSHAs(self, url, branch=None): | 135 | def _GetAllProjectsSHAs(self, url, branch=None): |
| 134 | """Get SHAs for all projects from superproject and save them in _project_shas. | 136 | """Get SHAs for all projects from superproject and save them in _project_shas. |
| 135 | 137 | ||
| 136 | Args: | 138 | Args: |
| 137 | url: superproject's url to be passed to git clone. | 139 | url: superproject's url to be passed to git clone or pull. |
| 138 | branch: the branchname to be passed as argument to git clone. | 140 | branch: The branchname to be passed as argument to git clone or pull. |
| 139 | 141 | ||
| 140 | Returns: | 142 | Returns: |
| 141 | A dictionary with the projects/SHAs instead of None. | 143 | A dictionary with the projects/SHAs instead of None. |
| 142 | """ | 144 | """ |
| 143 | if not url: | 145 | if not url: |
| 144 | raise ValueError('url argument is not supplied.') | 146 | raise ValueError('url argument is not supplied.') |
| 147 | do_clone = True | ||
| 145 | if os.path.exists(self._superproject_path): | 148 | if os.path.exists(self._superproject_path): |
| 146 | if not self._Pull(): | 149 | if not self._Pull(): |
| 147 | raise GitError('git pull failed for url: %s' % url) | 150 | # If pull fails due to a corrupted git directory, then do a git clone. |
| 148 | else: | 151 | platform_utils.rmtree(self._superproject_path) |
| 152 | else: | ||
| 153 | do_clone = False | ||
| 154 | if do_clone: | ||
| 149 | if not self._Clone(url, branch): | 155 | if not self._Clone(url, branch): |
| 150 | raise GitError('git clone failed for url: %s' % url) | 156 | raise GitError('git clone failed for url: %s' % url) |
| 151 | 157 | ||
| @@ -168,3 +174,67 @@ class Superproject(object): | |||
| 168 | 174 | ||
| 169 | self._project_shas = shas | 175 | self._project_shas = shas |
| 170 | return shas | 176 | return shas |
| 177 | |||
| 178 | def _WriteManfiestFile(self, manifest): | ||
| 179 | """Writes manifest to a file. | ||
| 180 | |||
| 181 | Args: | ||
| 182 | manifest: A Manifest object that is to be written to a file. | ||
| 183 | |||
| 184 | Returns: | ||
| 185 | manifest_path: Path name of the file into which manifest is written instead of None. | ||
| 186 | """ | ||
| 187 | if not os.path.exists(self._superproject_path): | ||
| 188 | print('error: missing superproject directory %s' % | ||
| 189 | self._superproject_path, | ||
| 190 | file=sys.stderr) | ||
| 191 | return None | ||
| 192 | manifest_str = manifest.ToXml().toxml() | ||
| 193 | manifest_path = self._manifest_path | ||
| 194 | try: | ||
| 195 | with open(manifest_path, 'w', encoding='utf-8') as fp: | ||
| 196 | fp.write(manifest_str) | ||
| 197 | except IOError as e: | ||
| 198 | print('error: cannot write manifest to %s:\n%s' | ||
| 199 | % (manifest_path, e), | ||
| 200 | file=sys.stderr) | ||
| 201 | return None | ||
| 202 | return manifest_path | ||
| 203 | |||
| 204 | def UpdateProjectsRevisionId(self, manifest, projects, url, branch=None): | ||
| 205 | """Update revisionId of every project in projects with the SHA. | ||
| 206 | |||
| 207 | Args: | ||
| 208 | manifest: A Manifest object that is to be written to a file. | ||
| 209 | projects: List of projects whose revisionId needs to be updated. | ||
| 210 | url: superproject's url to be passed to git clone or fetch. | ||
| 211 | branch: The branchname to be passed as argument to git clone or pull. | ||
| 212 | |||
| 213 | Returns: | ||
| 214 | manifest_path: Path name of the overriding manfiest file instead of None. | ||
| 215 | """ | ||
| 216 | try: | ||
| 217 | shas = self._GetAllProjectsSHAs(url=url, branch=branch) | ||
| 218 | except Exception as e: | ||
| 219 | print('error: Cannot get project SHAs for %s: %s: %s' % | ||
| 220 | (url, type(e).__name__, str(e)), | ||
| 221 | file=sys.stderr) | ||
| 222 | return None | ||
| 223 | |||
| 224 | projects_missing_shas = [] | ||
| 225 | for project in projects: | ||
| 226 | path = project.relpath | ||
| 227 | if not path: | ||
| 228 | continue | ||
| 229 | sha = shas.get(path) | ||
| 230 | if sha: | ||
| 231 | project.SetRevisionId(sha) | ||
| 232 | else: | ||
| 233 | projects_missing_shas.append(path) | ||
| 234 | if projects_missing_shas: | ||
| 235 | print('error: please file a bug using %s to report missing shas for: %s' % | ||
| 236 | (BUG_REPORT_URL, projects_missing_shas), file=sys.stderr) | ||
| 237 | return None | ||
| 238 | |||
| 239 | manifest_path = self._WriteManfiestFile(manifest) | ||
| 240 | return manifest_path | ||
diff --git a/subcmds/sync.py b/subcmds/sync.py index 225e565a..c0f605a8 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
| @@ -56,7 +56,7 @@ import gitc_utils | |||
| 56 | from project import Project | 56 | from project import Project |
| 57 | from project import RemoteSpec | 57 | from project import RemoteSpec |
| 58 | from command import Command, MirrorSafeCommand | 58 | from command import Command, MirrorSafeCommand |
| 59 | from error import BUG_REPORT_URL, RepoChangedException, GitError, ManifestParseError | 59 | from error import RepoChangedException, GitError, ManifestParseError |
| 60 | import platform_utils | 60 | import platform_utils |
| 61 | from project import SyncBuffer | 61 | from project import SyncBuffer |
| 62 | from progress import Progress | 62 | from progress import Progress |
| @@ -271,6 +271,47 @@ later is required to fix a server side protocol bug. | |||
| 271 | dest='repo_upgraded', action='store_true', | 271 | dest='repo_upgraded', action='store_true', |
| 272 | help=SUPPRESS_HELP) | 272 | help=SUPPRESS_HELP) |
| 273 | 273 | ||
| 274 | def _UpdateProjectsRevisionId(self, opt, args): | ||
| 275 | """Update revisionId of every project with the SHA from superproject. | ||
| 276 | |||
| 277 | This function updates each project's revisionId with SHA from superproject. | ||
| 278 | It writes the updated manifest into a file and reloads the manifest from it. | ||
| 279 | |||
| 280 | Args: | ||
| 281 | opt: Program options returned from optparse. See _Options(). | ||
| 282 | args: Arguments to pass to GetProjects. See the GetProjects | ||
| 283 | docstring for details. | ||
| 284 | |||
| 285 | Returns: | ||
| 286 | Returns path to the overriding manifest file. | ||
| 287 | """ | ||
| 288 | if not self.manifest.superproject: | ||
| 289 | print('error: superproject tag is not defined in manifest.xml', | ||
| 290 | file=sys.stderr) | ||
| 291 | sys.exit(1) | ||
| 292 | print('WARNING: --use-superproject is experimental and not ' | ||
| 293 | 'for general use', file=sys.stderr) | ||
| 294 | |||
| 295 | superproject_url = self.manifest.superproject['remote'].url | ||
| 296 | if not superproject_url: | ||
| 297 | print('error: superproject URL is not defined in manifest.xml', | ||
| 298 | file=sys.stderr) | ||
| 299 | sys.exit(1) | ||
| 300 | |||
| 301 | superproject = git_superproject.Superproject(self.manifest.repodir) | ||
| 302 | all_projects = self.GetProjects(args, | ||
| 303 | missing_ok=True, | ||
| 304 | submodules_ok=opt.fetch_submodules) | ||
| 305 | manifest_path = superproject.UpdateProjectsRevisionId(self.manifest, | ||
| 306 | all_projects, | ||
| 307 | url=superproject_url) | ||
| 308 | if not manifest_path: | ||
| 309 | print('error: Update of revsionId from superproject has failed', | ||
| 310 | file=sys.stderr) | ||
| 311 | sys.exit(1) | ||
| 312 | self._ReloadManifest(manifest_path) | ||
| 313 | return manifest_path | ||
| 314 | |||
| 274 | def _FetchProjectList(self, opt, projects, sem, *args, **kwargs): | 315 | def _FetchProjectList(self, opt, projects, sem, *args, **kwargs): |
| 275 | """Main function of the fetch threads. | 316 | """Main function of the fetch threads. |
| 276 | 317 | ||
| @@ -859,6 +900,9 @@ later is required to fix a server side protocol bug. | |||
| 859 | else: | 900 | else: |
| 860 | self._UpdateManifestProject(opt, mp, manifest_name) | 901 | self._UpdateManifestProject(opt, mp, manifest_name) |
| 861 | 902 | ||
| 903 | if opt.use_superproject: | ||
| 904 | manifest_name = self._UpdateProjectsRevisionId(opt, args) | ||
| 905 | |||
| 862 | if self.gitc_manifest: | 906 | if self.gitc_manifest: |
| 863 | gitc_manifest_projects = self.GetProjects(args, | 907 | gitc_manifest_projects = self.GetProjects(args, |
| 864 | missing_ok=True) | 908 | missing_ok=True) |
| @@ -898,41 +942,6 @@ later is required to fix a server side protocol bug. | |||
| 898 | missing_ok=True, | 942 | missing_ok=True, |
| 899 | submodules_ok=opt.fetch_submodules) | 943 | submodules_ok=opt.fetch_submodules) |
| 900 | 944 | ||
| 901 | if opt.use_superproject: | ||
| 902 | if not self.manifest.superproject: | ||
| 903 | print('error: superproject tag is not defined in manifest.xml', | ||
| 904 | file=sys.stderr) | ||
| 905 | sys.exit(1) | ||
| 906 | print('WARNING: --use-superproject is experimental and not ' | ||
| 907 | 'for general use', file=sys.stderr) | ||
| 908 | superproject_url = self.manifest.superproject['remote'].url | ||
| 909 | if not superproject_url: | ||
| 910 | print('error: superproject URL is not defined in manifest.xml', | ||
| 911 | file=sys.stderr) | ||
| 912 | sys.exit(1) | ||
| 913 | superproject = git_superproject.Superproject(self.manifest.repodir) | ||
| 914 | try: | ||
| 915 | superproject_shas = superproject.GetAllProjectsSHAs(url=superproject_url) | ||
| 916 | except Exception as e: | ||
| 917 | print('error: Cannot get project SHAs for %s: %s: %s' % | ||
| 918 | (superproject_url, type(e).__name__, str(e)), | ||
| 919 | file=sys.stderr) | ||
| 920 | sys.exit(1) | ||
| 921 | projects_missing_shas = [] | ||
| 922 | for project in all_projects: | ||
| 923 | path = project.relpath | ||
| 924 | if not path: | ||
| 925 | continue | ||
| 926 | sha = superproject_shas.get(path) | ||
| 927 | if sha: | ||
| 928 | project.SetRevisionId(sha) | ||
| 929 | else: | ||
| 930 | projects_missing_shas.append(path) | ||
| 931 | if projects_missing_shas: | ||
| 932 | print('error: please file a bug using %s to report missing shas for: %s' % | ||
| 933 | (BUG_REPORT_URL, projects_missing_shas), file=sys.stderr) | ||
| 934 | sys.exit(1) | ||
| 935 | |||
| 936 | err_network_sync = False | 945 | err_network_sync = False |
| 937 | err_update_projects = False | 946 | err_update_projects = False |
| 938 | err_checkout = False | 947 | err_checkout = False |
diff --git a/tests/test_git_superproject.py b/tests/test_git_superproject.py index 4012ec26..d2c2f501 100644 --- a/tests/test_git_superproject.py +++ b/tests/test_git_superproject.py | |||
| @@ -21,6 +21,7 @@ from unittest import mock | |||
| 21 | 21 | ||
| 22 | from error import GitError | 22 | from error import GitError |
| 23 | import git_superproject | 23 | import git_superproject |
| 24 | import manifest_xml | ||
| 24 | import platform_utils | 25 | import platform_utils |
| 25 | 26 | ||
| 26 | 27 | ||
| @@ -31,27 +32,43 @@ class SuperprojectTestCase(unittest.TestCase): | |||
| 31 | """Set up superproject every time.""" | 32 | """Set up superproject every time.""" |
| 32 | self.tempdir = tempfile.mkdtemp(prefix='repo_tests') | 33 | self.tempdir = tempfile.mkdtemp(prefix='repo_tests') |
| 33 | self.repodir = os.path.join(self.tempdir, '.repo') | 34 | self.repodir = os.path.join(self.tempdir, '.repo') |
| 34 | os.mkdir(self.repodir) | ||
| 35 | self._superproject = git_superproject.Superproject(self.repodir) | 35 | self._superproject = git_superproject.Superproject(self.repodir) |
| 36 | self.manifest_file = os.path.join( | ||
| 37 | self.repodir, manifest_xml.MANIFEST_FILE_NAME) | ||
| 38 | os.mkdir(self.repodir) | ||
| 39 | |||
| 40 | # The manifest parsing really wants a git repo currently. | ||
| 41 | gitdir = os.path.join(self.repodir, 'manifests.git') | ||
| 42 | os.mkdir(gitdir) | ||
| 43 | with open(os.path.join(gitdir, 'config'), 'w') as fp: | ||
| 44 | fp.write("""[remote "origin"] | ||
| 45 | url = https://localhost:0/manifest | ||
| 46 | """) | ||
| 36 | 47 | ||
| 37 | def tearDown(self): | 48 | def tearDown(self): |
| 38 | """Tear down superproject every time.""" | 49 | """Tear down superproject every time.""" |
| 39 | platform_utils.rmtree(self.tempdir) | 50 | platform_utils.rmtree(self.tempdir) |
| 40 | 51 | ||
| 52 | def getXmlManifest(self, data): | ||
| 53 | """Helper to initialize a manifest for testing.""" | ||
| 54 | with open(self.manifest_file, 'w') as fp: | ||
| 55 | fp.write(data) | ||
| 56 | return manifest_xml.XmlManifest(self.repodir, self.manifest_file) | ||
| 57 | |||
| 41 | def test_superproject_get_project_shas_no_url(self): | 58 | def test_superproject_get_project_shas_no_url(self): |
| 42 | """Test with no url.""" | 59 | """Test with no url.""" |
| 43 | with self.assertRaises(ValueError): | 60 | with self.assertRaises(ValueError): |
| 44 | self._superproject.GetAllProjectsSHAs(url=None) | 61 | self._superproject._GetAllProjectsSHAs(url=None) |
| 45 | 62 | ||
| 46 | def test_superproject_get_project_shas_invalid_url(self): | 63 | def test_superproject_get_project_shas_invalid_url(self): |
| 47 | """Test with an invalid url.""" | 64 | """Test with an invalid url.""" |
| 48 | with self.assertRaises(GitError): | 65 | with self.assertRaises(GitError): |
| 49 | self._superproject.GetAllProjectsSHAs(url='localhost') | 66 | self._superproject._GetAllProjectsSHAs(url='localhost') |
| 50 | 67 | ||
| 51 | def test_superproject_get_project_shas_invalid_branch(self): | 68 | def test_superproject_get_project_shas_invalid_branch(self): |
| 52 | """Test with an invalid branch.""" | 69 | """Test with an invalid branch.""" |
| 53 | with self.assertRaises(GitError): | 70 | with self.assertRaises(GitError): |
| 54 | self._superproject.GetAllProjectsSHAs( | 71 | self._superproject._GetAllProjectsSHAs( |
| 55 | url='sso://android/platform/superproject', | 72 | url='sso://android/platform/superproject', |
| 56 | branch='junk') | 73 | branch='junk') |
| 57 | 74 | ||
| @@ -59,14 +76,14 @@ class SuperprojectTestCase(unittest.TestCase): | |||
| 59 | """Test with _Clone failing.""" | 76 | """Test with _Clone failing.""" |
| 60 | with self.assertRaises(GitError): | 77 | with self.assertRaises(GitError): |
| 61 | with mock.patch.object(self._superproject, '_Clone', return_value=False): | 78 | with mock.patch.object(self._superproject, '_Clone', return_value=False): |
| 62 | self._superproject.GetAllProjectsSHAs(url='localhost') | 79 | self._superproject._GetAllProjectsSHAs(url='localhost') |
| 63 | 80 | ||
| 64 | def test_superproject_get_project_shas_mock_pull(self): | 81 | def test_superproject_get_project_shas_mock_pull(self): |
| 65 | """Test with _Pull failing.""" | 82 | """Test with _Pull failing.""" |
| 66 | with self.assertRaises(GitError): | 83 | with self.assertRaises(GitError): |
| 67 | with mock.patch.object(self._superproject, '_Clone', return_value=True): | 84 | with mock.patch.object(self._superproject, '_Clone', return_value=True): |
| 68 | with mock.patch.object(self._superproject, '_Pull', return_value=False): | 85 | with mock.patch.object(self._superproject, '_Pull', return_value=False): |
| 69 | self._superproject.GetAllProjectsSHAs(url='localhost') | 86 | self._superproject._GetAllProjectsSHAs(url='localhost') |
| 70 | 87 | ||
| 71 | def test_superproject_get_project_shas_mock_ls_tree(self): | 88 | def test_superproject_get_project_shas_mock_ls_tree(self): |
| 72 | """Test with LsTree being a mock.""" | 89 | """Test with LsTree being a mock.""" |
| @@ -77,13 +94,71 @@ class SuperprojectTestCase(unittest.TestCase): | |||
| 77 | '160000 commit ade9b7a0d874e25fff4bf2552488825c6f111928\tbuild/bazel\x00') | 94 | '160000 commit ade9b7a0d874e25fff4bf2552488825c6f111928\tbuild/bazel\x00') |
| 78 | with mock.patch.object(self._superproject, '_Clone', return_value=True): | 95 | with mock.patch.object(self._superproject, '_Clone', return_value=True): |
| 79 | with mock.patch.object(self._superproject, '_LsTree', return_value=data): | 96 | with mock.patch.object(self._superproject, '_LsTree', return_value=data): |
| 80 | shas = self._superproject.GetAllProjectsSHAs(url='localhost', branch='junk') | 97 | shas = self._superproject._GetAllProjectsSHAs(url='localhost', branch='junk') |
| 81 | self.assertEqual(shas, { | 98 | self.assertEqual(shas, { |
| 82 | 'art': '2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea', | 99 | 'art': '2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea', |
| 83 | 'bootable/recovery': 'e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06', | 100 | 'bootable/recovery': 'e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06', |
| 84 | 'build/bazel': 'ade9b7a0d874e25fff4bf2552488825c6f111928' | 101 | 'build/bazel': 'ade9b7a0d874e25fff4bf2552488825c6f111928' |
| 85 | }) | 102 | }) |
| 86 | 103 | ||
| 104 | def test_superproject_write_manifest_file(self): | ||
| 105 | """Test with writing manifest to a file after setting revisionId.""" | ||
| 106 | manifest = self.getXmlManifest(""" | ||
| 107 | <manifest> | ||
| 108 | <remote name="default-remote" fetch="http://localhost" /> | ||
| 109 | <default remote="default-remote" revision="refs/heads/main" /> | ||
| 110 | <project name="test-name"/> | ||
| 111 | </manifest> | ||
| 112 | """) | ||
| 113 | self.assertEqual(len(manifest.projects), 1) | ||
| 114 | project = manifest.projects[0] | ||
| 115 | project.SetRevisionId('ABCDEF') | ||
| 116 | # Create temporary directory so that it can write the file. | ||
| 117 | os.mkdir(self._superproject._superproject_path) | ||
| 118 | manifest_path = self._superproject._WriteManfiestFile(manifest) | ||
| 119 | self.assertIsNotNone(manifest_path) | ||
| 120 | with open(manifest_path, 'r') as fp: | ||
| 121 | manifest_xml = fp.read() | ||
| 122 | self.assertEqual( | ||
| 123 | manifest_xml, | ||
| 124 | '<?xml version="1.0" ?><manifest>' + | ||
| 125 | '<remote name="default-remote" fetch="http://localhost"/>' + | ||
| 126 | '<default remote="default-remote" revision="refs/heads/main"/>' + | ||
| 127 | '<project name="test-name" revision="ABCDEF"/>' + | ||
| 128 | '</manifest>') | ||
| 129 | |||
| 130 | def test_superproject_update_project_revision_id(self): | ||
| 131 | """Test with LsTree being a mock.""" | ||
| 132 | manifest = self.getXmlManifest(""" | ||
| 133 | <manifest> | ||
| 134 | <remote name="default-remote" fetch="http://localhost" /> | ||
| 135 | <default remote="default-remote" revision="refs/heads/main" /> | ||
| 136 | <project path="art" name="platform/art" /> | ||
| 137 | </manifest> | ||
| 138 | """) | ||
| 139 | self.assertEqual(len(manifest.projects), 1) | ||
| 140 | projects = manifest.projects | ||
| 141 | data = ('160000 commit 2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea\tart\x00' | ||
| 142 | '160000 commit e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06\tbootable/recovery\x00') | ||
| 143 | with mock.patch.object(self._superproject, '_Clone', return_value=True): | ||
| 144 | with mock.patch.object(self._superproject, '_Pull', return_value=True): | ||
| 145 | with mock.patch.object(self._superproject, '_LsTree', return_value=data): | ||
| 146 | # Create temporary directory so that it can write the file. | ||
| 147 | os.mkdir(self._superproject._superproject_path) | ||
| 148 | manifest_path = self._superproject.UpdateProjectsRevisionId( | ||
| 149 | manifest, projects, url='localhost') | ||
| 150 | self.assertIsNotNone(manifest_path) | ||
| 151 | with open(manifest_path, 'r') as fp: | ||
| 152 | manifest_xml = fp.read() | ||
| 153 | self.assertEqual( | ||
| 154 | manifest_xml, | ||
| 155 | '<?xml version="1.0" ?><manifest>' + | ||
| 156 | '<remote name="default-remote" fetch="http://localhost"/>' + | ||
| 157 | '<default remote="default-remote" revision="refs/heads/main"/>' + | ||
| 158 | '<project name="platform/art" path="art" ' + | ||
| 159 | 'revision="2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea"/>' + | ||
| 160 | '</manifest>') | ||
| 161 | |||
| 87 | 162 | ||
| 88 | if __name__ == '__main__': | 163 | if __name__ == '__main__': |
| 89 | unittest.main() | 164 | unittest.main() |
