summaryrefslogtreecommitdiffstats
path: root/gitc_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'gitc_utils.py')
-rw-r--r--gitc_utils.py166
1 files changed, 0 insertions, 166 deletions
diff --git a/gitc_utils.py b/gitc_utils.py
deleted file mode 100644
index 7b72048f..00000000
--- a/gitc_utils.py
+++ /dev/null
@@ -1,166 +0,0 @@
1# Copyright (C) 2015 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import os
16import multiprocessing
17import re
18import sys
19import time
20
21import git_command
22import git_config
23import wrapper
24
25from error import ManifestParseError
26
27NUM_BATCH_RETRIEVE_REVISIONID = 32
28
29
30def get_gitc_manifest_dir():
31 return wrapper.Wrapper().get_gitc_manifest_dir()
32
33
34def parse_clientdir(gitc_fs_path):
35 return wrapper.Wrapper().gitc_parse_clientdir(gitc_fs_path)
36
37
38def _get_project_revision(args):
39 """Worker for _set_project_revisions to lookup one project remote."""
40 (i, url, expr) = args
41 gitcmd = git_command.GitCommand(
42 None, ["ls-remote", url, expr], capture_stdout=True, cwd="/tmp"
43 )
44 rc = gitcmd.Wait()
45 return (i, rc, gitcmd.stdout.split("\t", 1)[0])
46
47
48def _set_project_revisions(projects):
49 """Sets the revisionExpr for a list of projects.
50
51 Because of the limit of open file descriptors allowed, length of projects
52 should not be overly large. Recommend calling this function multiple times
53 with each call not exceeding NUM_BATCH_RETRIEVE_REVISIONID projects.
54
55 Args:
56 projects: List of project objects to set the revionExpr for.
57 """
58 # Retrieve the commit id for each project based off of its current
59 # revisionExpr and it is not already a commit id.
60 with multiprocessing.Pool(NUM_BATCH_RETRIEVE_REVISIONID) as pool:
61 results_iter = pool.imap_unordered(
62 _get_project_revision,
63 (
64 (i, project.remote.url, project.revisionExpr)
65 for i, project in enumerate(projects)
66 if not git_config.IsId(project.revisionExpr)
67 ),
68 chunksize=8,
69 )
70 for i, rc, revisionExpr in results_iter:
71 project = projects[i]
72 if rc:
73 print(
74 "FATAL: Failed to retrieve revisionExpr for %s"
75 % project.name
76 )
77 pool.terminate()
78 sys.exit(1)
79 if not revisionExpr:
80 pool.terminate()
81 raise ManifestParseError(
82 "Invalid SHA-1 revision project %s (%s)"
83 % (project.remote.url, project.revisionExpr)
84 )
85 project.revisionExpr = revisionExpr
86
87
88def generate_gitc_manifest(gitc_manifest, manifest, paths=None):
89 """Generate a manifest for shafsd to use for this GITC client.
90
91 Args:
92 gitc_manifest: Current gitc manifest, or None if there isn't one yet.
93 manifest: A GitcManifest object loaded with the current repo manifest.
94 paths: List of project paths we want to update.
95 """
96
97 print(
98 "Generating GITC Manifest by fetching revision SHAs for each "
99 "project."
100 )
101 if paths is None:
102 paths = list(manifest.paths.keys())
103
104 groups = [x for x in re.split(r"[,\s]+", manifest.GetGroupsStr()) if x]
105
106 # Convert the paths to projects, and filter them to the matched groups.
107 projects = [manifest.paths[p] for p in paths]
108 projects = [p for p in projects if p.MatchesGroups(groups)]
109
110 if gitc_manifest is not None:
111 for path, proj in manifest.paths.items():
112 if not proj.MatchesGroups(groups):
113 continue
114
115 if not proj.upstream and not git_config.IsId(proj.revisionExpr):
116 proj.upstream = proj.revisionExpr
117
118 if path not in gitc_manifest.paths:
119 # Any new projects need their first revision, even if we weren't
120 # asked for them.
121 projects.append(proj)
122 elif path not in paths:
123 # And copy revisions from the previous manifest if we're not
124 # updating them now.
125 gitc_proj = gitc_manifest.paths[path]
126 if gitc_proj.old_revision:
127 proj.revisionExpr = None
128 proj.old_revision = gitc_proj.old_revision
129 else:
130 proj.revisionExpr = gitc_proj.revisionExpr
131
132 _set_project_revisions(projects)
133
134 if gitc_manifest is not None:
135 for path, proj in gitc_manifest.paths.items():
136 if proj.old_revision and path in paths:
137 # If we updated a project that has been started, keep the
138 # old-revision updated.
139 repo_proj = manifest.paths[path]
140 repo_proj.old_revision = repo_proj.revisionExpr
141 repo_proj.revisionExpr = None
142
143 # Convert URLs from relative to absolute.
144 for _name, remote in manifest.remotes.items():
145 remote.fetchUrl = remote.resolvedFetchUrl
146
147 # Save the manifest.
148 save_manifest(manifest)
149
150
151def save_manifest(manifest, client_dir=None):
152 """Save the manifest file in the client_dir.
153
154 Args:
155 manifest: Manifest object to save.
156 client_dir: Client directory to save the manifest in.
157 """
158 if not client_dir:
159 manifest_file = manifest.manifestFile
160 else:
161 manifest_file = os.path.join(client_dir, ".manifest")
162 with open(manifest_file, "w") as f:
163 manifest.Save(f, groups=manifest.GetGroupsStr())
164 # TODO(sbasi/jorg): Come up with a solution to remove the sleep below.
165 # Give the GITC filesystem time to register the manifest changes.
166 time.sleep(3)