1 |
commit: f3101b3adce6731790f80f83fafece54b7bd8a63 |
2 |
Author: Brian Harring <ferringb <AT> chromium <DOT> org> |
3 |
AuthorDate: Fri Sep 23 23:43:28 2011 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Sep 28 06:31:54 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=f3101b3a |
7 |
|
8 |
manifest: controllable per repo |
9 |
|
10 |
This adds three states to layout.conf key use-manifest; false, true, and strict. |
11 |
|
12 |
false means "don't use manifests at all" |
13 |
true means "use and generate manifests, but allow them to be missing" |
14 |
strict means "manifests must be used everywhere in this repo" |
15 |
|
16 |
BUG=chromium-os:11308 |
17 |
TEST=repoman manifest usage. |
18 |
|
19 |
--- |
20 |
man/make.conf.5 | 4 ---- |
21 |
man/portage.5 | 3 +++ |
22 |
pym/_emerge/EbuildFetcher.py | 21 ++++++++++++--------- |
23 |
pym/portage/const.py | 1 - |
24 |
pym/portage/manifest.py | 11 +++++++++-- |
25 |
pym/portage/package/ebuild/digestcheck.py | 3 +-- |
26 |
pym/portage/package/ebuild/digestgen.py | 6 ++++++ |
27 |
pym/portage/package/ebuild/doebuild.py | 7 +++---- |
28 |
pym/portage/repository/config.py | 15 ++++++++++++++- |
29 |
9 files changed, 48 insertions(+), 23 deletions(-) |
30 |
|
31 |
diff --git a/man/make.conf.5 b/man/make.conf.5 |
32 |
index 3f3efae..6c64686 100644 |
33 |
--- a/man/make.conf.5 |
34 |
+++ b/man/make.conf.5 |
35 |
@@ -204,10 +204,6 @@ non-developers as well. The \fBsandbox\fR feature is very important and |
36 |
should not be disabled by default. |
37 |
.RS |
38 |
.TP |
39 |
-.B allow\-missing\-manifests |
40 |
-Allow missing manifest entries. This is primarily useful for temporary |
41 |
-trees or instances where manifests aren't used. |
42 |
-.TP |
43 |
.B assume\-digests |
44 |
When commiting work to cvs with \fBrepoman\fR(1), assume that all existing |
45 |
SRC_URI digests are correct. This feature also affects digest generation via |
46 |
|
47 |
diff --git a/man/portage.5 b/man/portage.5 |
48 |
index 2af6676..1d9545a 100644 |
49 |
--- a/man/portage.5 |
50 |
+++ b/man/portage.5 |
51 |
@@ -781,6 +781,9 @@ aliases = foo-overlay |
52 |
sign\-manifests = false |
53 |
# thin\-manifests only contain DIST entries |
54 |
thin\-manifests = true |
55 |
+# indicate that this repo requires manifests for each package, and is |
56 |
+# considered a failure if a manifest file is missing/incorrect |
57 |
+use\-manifests = strict |
58 |
.fi |
59 |
.RE |
60 |
.TP |
61 |
|
62 |
diff --git a/pym/_emerge/EbuildFetcher.py b/pym/_emerge/EbuildFetcher.py |
63 |
index 4389f84..61c7848 100644 |
64 |
--- a/pym/_emerge/EbuildFetcher.py |
65 |
+++ b/pym/_emerge/EbuildFetcher.py |
66 |
@@ -21,7 +21,7 @@ class EbuildFetcher(SpawnProcess): |
67 |
|
68 |
__slots__ = ("config_pool", "ebuild_path", "fetchonly", "fetchall", |
69 |
"pkg", "prefetch") + \ |
70 |
- ("_digests", "_settings", "_uri_map") |
71 |
+ ("_digests", "_manifest", "_settings", "_uri_map") |
72 |
|
73 |
def already_fetched(self, settings): |
74 |
""" |
75 |
@@ -40,7 +40,7 @@ class EbuildFetcher(SpawnProcess): |
76 |
|
77 |
digests = self._get_digests() |
78 |
distdir = settings["DISTDIR"] |
79 |
- allow_missing = "allow-missing-manifests" in settings.features |
80 |
+ allow_missing = self._get_manifest().allow_missing |
81 |
|
82 |
for filename in uri_map: |
83 |
# Use stat rather than lstat since fetch() creates |
84 |
@@ -179,7 +179,7 @@ class EbuildFetcher(SpawnProcess): |
85 |
not in ('yes', 'true') |
86 |
|
87 |
rval = 1 |
88 |
- allow_missing = 'allow-missing-manifests' in self._settings.features |
89 |
+ allow_missing = self._get_manifest().allow_missing |
90 |
try: |
91 |
if fetch(self._uri_map, self._settings, fetchonly=self.fetchonly, |
92 |
digests=copy.deepcopy(self._get_digests()), |
93 |
@@ -203,13 +203,16 @@ class EbuildFetcher(SpawnProcess): |
94 |
raise AssertionError("ebuild not found for '%s'" % self.pkg.cpv) |
95 |
return self.ebuild_path |
96 |
|
97 |
+ def _get_manifest(self): |
98 |
+ if self._manifest is None: |
99 |
+ pkgdir = os.path.dirname(self._get_ebuild_path()) |
100 |
+ self._manifest = self.pkg.root_config.settings.repositories.get_repo_for_location( |
101 |
+ os.path.dirname(os.path.dirname(pkgdir))).load_manifest(pkgdir, None) |
102 |
+ return self._manifest |
103 |
+ |
104 |
def _get_digests(self): |
105 |
- if self._digests is not None: |
106 |
- return self._digests |
107 |
- pkgdir = os.path.dirname(self._get_ebuild_path()) |
108 |
- mf = self.pkg.root_config.settings.repositories.get_repo_for_location( |
109 |
- os.path.dirname(os.path.dirname(pkgdir))) |
110 |
- self._digests = mf.load_manifest(pkgdir, None).getTypeDigests("DIST") |
111 |
+ if self._digests is None: |
112 |
+ self._digests = self._get_manifest().getTypeDigests("DIST") |
113 |
return self._digests |
114 |
|
115 |
def _get_uri_map(self): |
116 |
|
117 |
diff --git a/pym/portage/const.py b/pym/portage/const.py |
118 |
index f24a1a9..8b5f4ac 100644 |
119 |
--- a/pym/portage/const.py |
120 |
+++ b/pym/portage/const.py |
121 |
@@ -86,7 +86,6 @@ EBUILD_PHASES = ("pretend", "setup", "unpack", "prepare", "configure" |
122 |
"package", "preinst", "postinst","prerm", "postrm", |
123 |
"nofetch", "config", "info", "other") |
124 |
SUPPORTED_FEATURES = frozenset([ |
125 |
- "allow-missing-manifests", |
126 |
"assume-digests", "binpkg-logs", "buildpkg", "buildsyspkg", "candy", |
127 |
"ccache", "chflags", "clean-logs", |
128 |
"collision-protect", "compress-build-logs", |
129 |
|
130 |
diff --git a/pym/portage/manifest.py b/pym/portage/manifest.py |
131 |
index 449f9fd..7cac09c 100644 |
132 |
--- a/pym/portage/manifest.py |
133 |
+++ b/pym/portage/manifest.py |
134 |
@@ -100,7 +100,8 @@ class Manifest2Entry(ManifestEntry): |
135 |
class Manifest(object): |
136 |
parsers = (parseManifest2,) |
137 |
def __init__(self, pkgdir, distdir, fetchlist_dict=None, |
138 |
- manifest1_compat=DeprecationWarning, from_scratch=False, thin=False): |
139 |
+ manifest1_compat=DeprecationWarning, from_scratch=False, thin=False, |
140 |
+ allow_missing=False, allow_create=True): |
141 |
""" Create new Manifest instance for package in pkgdir. |
142 |
Do not parse Manifest file if from_scratch == True (only for internal use) |
143 |
The fetchlist_dict parameter is required only for generation of |
144 |
@@ -135,6 +136,8 @@ class Manifest(object): |
145 |
self.guessType = guessThinManifestFileType |
146 |
else: |
147 |
self.guessType = guessManifestFileType |
148 |
+ self.allow_missing = allow_missing |
149 |
+ self.allow_create = allow_create |
150 |
|
151 |
def getFullname(self): |
152 |
""" Returns the absolute path to the Manifest file for this instance """ |
153 |
@@ -237,6 +240,8 @@ class Manifest(object): |
154 |
|
155 |
def write(self, sign=False, force=False): |
156 |
""" Write Manifest instance to disk, optionally signing it """ |
157 |
+ if not self.allow_create: |
158 |
+ return |
159 |
self.checkIntegrity() |
160 |
try: |
161 |
myentries = list(self._createManifestEntries()) |
162 |
@@ -265,7 +270,7 @@ class Manifest(object): |
163 |
if myentries: |
164 |
write_atomic(self.getFullname(), "".join("%s\n" % |
165 |
str(myentry) for myentry in myentries)) |
166 |
- else: |
167 |
+ elif self.thin: |
168 |
# With thin manifest, there's no need to have |
169 |
# a Manifest file if there are no DIST entries. |
170 |
try: |
171 |
@@ -330,6 +335,8 @@ class Manifest(object): |
172 |
distfiles to raise a FileNotFound exception for (if no file or existing |
173 |
checksums are available), and defaults to all distfiles when not |
174 |
specified.""" |
175 |
+ if not self.allow_create: |
176 |
+ return |
177 |
if checkExisting: |
178 |
self.checkAllHashes() |
179 |
if assumeDistHashesSometimes or assumeDistHashesAlways: |
180 |
|
181 |
diff --git a/pym/portage/package/ebuild/digestcheck.py b/pym/portage/package/ebuild/digestcheck.py |
182 |
index 6cbaad9..067aacc 100644 |
183 |
--- a/pym/portage/package/ebuild/digestcheck.py |
184 |
+++ b/pym/portage/package/ebuild/digestcheck.py |
185 |
@@ -27,7 +27,6 @@ def digestcheck(myfiles, mysettings, strict=False, justmanifest=None, mf=None): |
186 |
|
187 |
if mysettings.get("EBUILD_SKIP_MANIFEST") == "1": |
188 |
return 1 |
189 |
- allow_missing = "allow-missing-manifests" in mysettings.features |
190 |
pkgdir = mysettings["O"] |
191 |
if mf is None: |
192 |
mf = mysettings.repositories.get_repo_for_location( |
193 |
@@ -72,7 +71,7 @@ def digestcheck(myfiles, mysettings, strict=False, justmanifest=None, mf=None): |
194 |
writemsg(_("!!! Got: %s\n") % e.value[2], noiselevel=-1) |
195 |
writemsg(_("!!! Expected: %s\n") % e.value[3], noiselevel=-1) |
196 |
return 0 |
197 |
- if allow_missing or mf.thin: |
198 |
+ if mf.thin or mf.allow_missing: |
199 |
# In this case we ignore any missing digests that |
200 |
# would otherwise be detected below. |
201 |
return 1 |
202 |
|
203 |
diff --git a/pym/portage/package/ebuild/digestgen.py b/pym/portage/package/ebuild/digestgen.py |
204 |
index d4146dd..f14368d 100644 |
205 |
--- a/pym/portage/package/ebuild/digestgen.py |
206 |
+++ b/pym/portage/package/ebuild/digestgen.py |
207 |
@@ -60,6 +60,12 @@ def digestgen(myarchives=None, mysettings=None, myportdb=None): |
208 |
|
209 |
mf = mf.load_manifest(mysettings["O"], mysettings["DISTDIR"], |
210 |
fetchlist_dict=fetchlist_dict) |
211 |
+ |
212 |
+ if not mf.allow_create: |
213 |
+ writemsg_stdout(_(">>> Skipping creating Manifest for %s; " |
214 |
+ "repository is configured to not use them\n") % mysettings["O"]) |
215 |
+ return 1 |
216 |
+ |
217 |
# Don't require all hashes since that can trigger excessive |
218 |
# fetches when sufficient digests already exist. To ease transition |
219 |
# while Manifest 1 is being removed, only require hashes that will |
220 |
|
221 |
diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py |
222 |
index e89d77d..bd33d91 100644 |
223 |
--- a/pym/portage/package/ebuild/doebuild.py |
224 |
+++ b/pym/portage/package/ebuild/doebuild.py |
225 |
@@ -484,7 +484,6 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, |
226 |
global _doebuild_manifest_cache |
227 |
pkgdir = os.path.dirname(myebuild) |
228 |
manifest_path = os.path.join(pkgdir, "Manifest") |
229 |
- allow_missing_manifests = "allow-missing-manifests" in mysettings.features |
230 |
if tree == "porttree": |
231 |
repo_config = mysettings.repositories.get_repo_for_location( |
232 |
os.path.dirname(os.path.dirname(pkgdir))) |
233 |
@@ -497,7 +496,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, |
234 |
not repo_config.thin_manifest and \ |
235 |
mydo not in ("digest", "manifest", "help") and \ |
236 |
not portage._doebuild_manifest_exempt_depend and \ |
237 |
- not (allow_missing_manifests and not os.path.exists(manifest_path)): |
238 |
+ not (repo_config.allow_missing_manifests and not os.path.exists(manifest_path)): |
239 |
# Always verify the ebuild checksums before executing it. |
240 |
global _doebuild_broken_ebuilds |
241 |
|
242 |
@@ -522,7 +521,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, |
243 |
try: |
244 |
mf.checkFileHashes("EBUILD", os.path.basename(myebuild)) |
245 |
except KeyError: |
246 |
- if not (allow_missing_manifests and |
247 |
+ if not (mf.allow_missing and |
248 |
os.path.basename(myebuild) not in mf.fhashdict["EBUILD"]): |
249 |
out = portage.output.EOutput() |
250 |
out.eerror(_("Missing digest for '%s'") % (myebuild,)) |
251 |
@@ -547,7 +546,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, |
252 |
if mf.getFullname() in _doebuild_broken_manifests: |
253 |
return 1 |
254 |
|
255 |
- if mf is not _doebuild_manifest_cache and not allow_missing_manifests: |
256 |
+ if mf is not _doebuild_manifest_cache and not mf.allow_missing: |
257 |
|
258 |
# Make sure that all of the ebuilds are |
259 |
# actually listed in the Manifest. |
260 |
|
261 |
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py |
262 |
index 8b1e641..3cb5501 100644 |
263 |
--- a/pym/portage/repository/config.py |
264 |
+++ b/pym/portage/repository/config.py |
265 |
@@ -42,7 +42,8 @@ class RepoConfig(object): |
266 |
"""Stores config of one repository""" |
267 |
|
268 |
__slots__ = ['aliases', 'eclass_overrides', 'eclass_locations', 'location', 'user_location', 'masters', 'main_repo', |
269 |
- 'missing_repo_name', 'name', 'priority', 'sync', 'format', 'sign_manifest', 'thin_manifest'] |
270 |
+ 'missing_repo_name', 'name', 'priority', 'sync', 'format', 'sign_manifest', 'thin_manifest', |
271 |
+ 'allow_missing_manifest', 'create_manifest', 'disable_manifest'] |
272 |
|
273 |
def __init__(self, name, repo_opts): |
274 |
"""Build a RepoConfig with options in repo_opts |
275 |
@@ -113,9 +114,16 @@ class RepoConfig(object): |
276 |
self.missing_repo_name = missing |
277 |
self.sign_manifest = True |
278 |
self.thin_manifest = False |
279 |
+ self.allow_missing_manifest = False |
280 |
+ self.create_manifest = True |
281 |
+ self.disable_manifest = False |
282 |
|
283 |
def load_manifest(self, *args, **kwds): |
284 |
kwds['thin'] = self.thin_manifest |
285 |
+ kwds['allow_missing'] = self.allow_missing_manifest |
286 |
+ kwds['allow_create'] = self.create_manifest |
287 |
+ if self.disable_manifest: |
288 |
+ kwds['from_scratch'] = True |
289 |
return manifest.Manifest(*args, **kwds) |
290 |
|
291 |
def update(self, new_repo): |
292 |
@@ -345,6 +353,11 @@ class RepoConfigLoader(object): |
293 |
if layout_data.get('thin-manifests', '').lower() == 'true': |
294 |
repo.thin_manifest = True |
295 |
|
296 |
+ manifest_policy = layout_data.get('use-manifests', 'strict').lower() |
297 |
+ repo.allow_missing_manifest = manifest_policy != 'strict' |
298 |
+ repo.create_manifest = manifest_policy != 'false' |
299 |
+ repo.disable_manifest = manifest_policy == 'false' |
300 |
+ |
301 |
#Take aliases into account. |
302 |
new_prepos = {} |
303 |
for repo_name, repo in prepos.items(): |