diff options
Diffstat (limited to 'subcmds/init.py')
-rw-r--r-- | subcmds/init.py | 99 |
1 files changed, 79 insertions, 20 deletions
diff --git a/subcmds/init.py b/subcmds/init.py index 4182262e..9c6b2ad9 100644 --- a/subcmds/init.py +++ b/subcmds/init.py | |||
@@ -12,10 +12,10 @@ | |||
12 | # See the License for the specific language governing permissions and | 12 | # See the License for the specific language governing permissions and |
13 | # limitations under the License. | 13 | # limitations under the License. |
14 | 14 | ||
15 | import optparse | ||
16 | import os | 15 | import os |
17 | import platform | 16 | import platform |
18 | import re | 17 | import re |
18 | import subprocess | ||
19 | import sys | 19 | import sys |
20 | import urllib.parse | 20 | import urllib.parse |
21 | 21 | ||
@@ -25,13 +25,14 @@ from error import ManifestParseError | |||
25 | from project import SyncBuffer | 25 | from project import SyncBuffer |
26 | from git_config import GitConfig | 26 | from git_config import GitConfig |
27 | from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD | 27 | from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD |
28 | import fetch | ||
28 | import git_superproject | 29 | import git_superproject |
29 | import platform_utils | 30 | import platform_utils |
30 | from wrapper import Wrapper | 31 | from wrapper import Wrapper |
31 | 32 | ||
32 | 33 | ||
33 | class Init(InteractiveCommand, MirrorSafeCommand): | 34 | class Init(InteractiveCommand, MirrorSafeCommand): |
34 | common = True | 35 | COMMON = True |
35 | helpSummary = "Initialize a repo client checkout in the current directory" | 36 | helpSummary = "Initialize a repo client checkout in the current directory" |
36 | helpUsage = """ | 37 | helpUsage = """ |
37 | %prog [options] [manifest url] | 38 | %prog [options] [manifest url] |
@@ -54,6 +55,12 @@ The optional -m argument can be used to specify an alternate manifest | |||
54 | to be used. If no manifest is specified, the manifest default.xml | 55 | to be used. If no manifest is specified, the manifest default.xml |
55 | will be used. | 56 | will be used. |
56 | 57 | ||
58 | If the --standalone-manifest argument is set, the manifest will be downloaded | ||
59 | directly from the specified --manifest-url as a static file (rather than | ||
60 | setting up a manifest git checkout). With --standalone-manifest, the manifest | ||
61 | will be fully static and will not be re-downloaded during subsesquent | ||
62 | `repo init` and `repo sync` calls. | ||
63 | |||
57 | The --reference option can be used to point to a directory that | 64 | The --reference option can be used to point to a directory that |
58 | has the content of a --mirror sync. This will make the working | 65 | has the content of a --mirror sync. This will make the working |
59 | directory use as much data as possible from the local reference | 66 | directory use as much data as possible from the local reference |
@@ -97,15 +104,38 @@ to update the working directory files. | |||
97 | """ | 104 | """ |
98 | superproject = git_superproject.Superproject(self.manifest, | 105 | superproject = git_superproject.Superproject(self.manifest, |
99 | self.repodir, | 106 | self.repodir, |
107 | self.git_event_log, | ||
100 | quiet=opt.quiet) | 108 | quiet=opt.quiet) |
101 | if not superproject.Sync(): | 109 | sync_result = superproject.Sync() |
102 | print('error: git update of superproject failed', file=sys.stderr) | 110 | if not sync_result.success: |
103 | sys.exit(1) | 111 | print('warning: git update of superproject failed, repo sync will not ' |
112 | 'use superproject to fetch source; while this error is not fatal, ' | ||
113 | 'and you can continue to run repo sync, please run repo init with ' | ||
114 | 'the --no-use-superproject option to stop seeing this warning', | ||
115 | file=sys.stderr) | ||
116 | if sync_result.fatal and opt.use_superproject is not None: | ||
117 | sys.exit(1) | ||
104 | 118 | ||
105 | def _SyncManifest(self, opt): | 119 | def _SyncManifest(self, opt): |
106 | m = self.manifest.manifestProject | 120 | m = self.manifest.manifestProject |
107 | is_new = not m.Exists | 121 | is_new = not m.Exists |
108 | 122 | ||
123 | # If repo has already been initialized, we take -u with the absence of | ||
124 | # --standalone-manifest to mean "transition to a standard repo set up", | ||
125 | # which necessitates starting fresh. | ||
126 | # If --standalone-manifest is set, we always tear everything down and start | ||
127 | # anew. | ||
128 | if not is_new: | ||
129 | was_standalone_manifest = m.config.GetString('manifest.standalone') | ||
130 | if opt.standalone_manifest or ( | ||
131 | was_standalone_manifest and opt.manifest_url): | ||
132 | m.config.ClearCache() | ||
133 | if m.gitdir and os.path.exists(m.gitdir): | ||
134 | platform_utils.rmtree(m.gitdir) | ||
135 | if m.worktree and os.path.exists(m.worktree): | ||
136 | platform_utils.rmtree(m.worktree) | ||
137 | |||
138 | is_new = not m.Exists | ||
109 | if is_new: | 139 | if is_new: |
110 | if not opt.manifest_url: | 140 | if not opt.manifest_url: |
111 | print('fatal: manifest url is required.', file=sys.stderr) | 141 | print('fatal: manifest url is required.', file=sys.stderr) |
@@ -130,6 +160,19 @@ to update the working directory files. | |||
130 | 160 | ||
131 | m._InitGitDir(mirror_git=mirrored_manifest_git) | 161 | m._InitGitDir(mirror_git=mirrored_manifest_git) |
132 | 162 | ||
163 | # If standalone_manifest is set, mark the project as "standalone" -- we'll | ||
164 | # still do much of the manifests.git set up, but will avoid actual syncs to | ||
165 | # a remote. | ||
166 | standalone_manifest = False | ||
167 | if opt.standalone_manifest: | ||
168 | standalone_manifest = True | ||
169 | elif not opt.manifest_url: | ||
170 | # If -u is set and --standalone-manifest is not, then we're not in | ||
171 | # standalone mode. Otherwise, use config to infer what we were in the last | ||
172 | # init. | ||
173 | standalone_manifest = bool(m.config.GetString('manifest.standalone')) | ||
174 | m.config.SetString('manifest.standalone', opt.manifest_url) | ||
175 | |||
133 | self._ConfigureDepth(opt) | 176 | self._ConfigureDepth(opt) |
134 | 177 | ||
135 | # Set the remote URL before the remote branch as we might need it below. | 178 | # Set the remote URL before the remote branch as we might need it below. |
@@ -139,22 +182,23 @@ to update the working directory files. | |||
139 | r.ResetFetch() | 182 | r.ResetFetch() |
140 | r.Save() | 183 | r.Save() |
141 | 184 | ||
142 | if opt.manifest_branch: | 185 | if not standalone_manifest: |
143 | if opt.manifest_branch == 'HEAD': | 186 | if opt.manifest_branch: |
144 | opt.manifest_branch = m.ResolveRemoteHead() | 187 | if opt.manifest_branch == 'HEAD': |
145 | if opt.manifest_branch is None: | 188 | opt.manifest_branch = m.ResolveRemoteHead() |
146 | print('fatal: unable to resolve HEAD', file=sys.stderr) | 189 | if opt.manifest_branch is None: |
147 | sys.exit(1) | 190 | print('fatal: unable to resolve HEAD', file=sys.stderr) |
148 | m.revisionExpr = opt.manifest_branch | 191 | sys.exit(1) |
149 | else: | 192 | m.revisionExpr = opt.manifest_branch |
150 | if is_new: | ||
151 | default_branch = m.ResolveRemoteHead() | ||
152 | if default_branch is None: | ||
153 | # If the remote doesn't have HEAD configured, default to master. | ||
154 | default_branch = 'refs/heads/master' | ||
155 | m.revisionExpr = default_branch | ||
156 | else: | 193 | else: |
157 | m.PreSync() | 194 | if is_new: |
195 | default_branch = m.ResolveRemoteHead() | ||
196 | if default_branch is None: | ||
197 | # If the remote doesn't have HEAD configured, default to master. | ||
198 | default_branch = 'refs/heads/master' | ||
199 | m.revisionExpr = default_branch | ||
200 | else: | ||
201 | m.PreSync() | ||
158 | 202 | ||
159 | groups = re.split(r'[,\s]+', opt.groups) | 203 | groups = re.split(r'[,\s]+', opt.groups) |
160 | all_platforms = ['linux', 'darwin', 'windows'] | 204 | all_platforms = ['linux', 'darwin', 'windows'] |
@@ -244,6 +288,16 @@ to update the working directory files. | |||
244 | if opt.use_superproject is not None: | 288 | if opt.use_superproject is not None: |
245 | m.config.SetBoolean('repo.superproject', opt.use_superproject) | 289 | m.config.SetBoolean('repo.superproject', opt.use_superproject) |
246 | 290 | ||
291 | if standalone_manifest: | ||
292 | if is_new: | ||
293 | manifest_name = 'default.xml' | ||
294 | manifest_data = fetch.fetch_file(opt.manifest_url) | ||
295 | dest = os.path.join(m.worktree, manifest_name) | ||
296 | os.makedirs(os.path.dirname(dest), exist_ok=True) | ||
297 | with open(dest, 'wb') as f: | ||
298 | f.write(manifest_data) | ||
299 | return | ||
300 | |||
247 | if not m.Sync_NetworkHalf(is_new=is_new, quiet=opt.quiet, verbose=opt.verbose, | 301 | if not m.Sync_NetworkHalf(is_new=is_new, quiet=opt.quiet, verbose=opt.verbose, |
248 | clone_bundle=opt.clone_bundle, | 302 | clone_bundle=opt.clone_bundle, |
249 | current_branch_only=opt.current_branch_only, | 303 | current_branch_only=opt.current_branch_only, |
@@ -420,6 +474,11 @@ to update the working directory files. | |||
420 | if opt.archive and opt.mirror: | 474 | if opt.archive and opt.mirror: |
421 | self.OptionParser.error('--mirror and --archive cannot be used together.') | 475 | self.OptionParser.error('--mirror and --archive cannot be used together.') |
422 | 476 | ||
477 | if opt.standalone_manifest and ( | ||
478 | opt.manifest_branch or opt.manifest_name != 'default.xml'): | ||
479 | self.OptionParser.error('--manifest-branch and --manifest-name cannot' | ||
480 | ' be used with --standalone-manifest.') | ||
481 | |||
423 | if args: | 482 | if args: |
424 | if opt.manifest_url: | 483 | if opt.manifest_url: |
425 | self.OptionParser.error( | 484 | self.OptionParser.error( |