2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
7 # This block ensures that ^C interrupts are handled quietly.
11 def exithandler(signum,frame):
12 signal.signal(signal.SIGINT, signal.SIG_IGN)
13 signal.signal(signal.SIGTERM, signal.SIG_IGN)
16 signal.signal(signal.SIGINT, exithandler)
17 signal.signal(signal.SIGTERM, exithandler)
19 except KeyboardInterrupt:
22 def debug_signal(signum, frame):
25 signal.signal(signal.SIGUSR1, debug_signal)
30 description = "See the ebuild(1) man page for more info"
31 usage = "Usage: ebuild <ebuild file> <command> [command] ..."
32 parser = optparse.OptionParser(description=description, usage=usage)
34 force_help = "When used together with the digest or manifest " + \
35 "command, this option forces regeneration of digests for all " + \
36 "distfiles associated with the current ebuild. Any distfiles " + \
37 "that do not already exist in ${DISTDIR} will be automatically fetched."
39 parser.add_option("--force", help=force_help, action="store_true", dest="force")
40 parser.add_option("--debug", help="show debug output",
41 action="store_true", dest="debug")
42 parser.add_option("--ignore-default-opts",
44 help="do not use the EBUILD_DEFAULT_OPTS environment variable")
45 parser.add_option("--skip-manifest", help="skip all manifest checks",
46 action="store_true", dest="skip_manifest")
48 opts, pargs = parser.parse_args(args=sys.argv[1:])
51 parser.error("missing required args")
54 print "Disabling noauto in features... merge disables it. (qmerge doesn't)"
55 os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " -noauto"
57 os.environ["PORTAGE_CALLER"]="ebuild"
61 from os import path as osp
62 sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
65 if not opts.ignore_default_opts:
66 default_opts = portage.settings.get("EBUILD_DEFAULT_OPTS", "").split()
67 opts, pargs = parser.parse_args(default_opts + sys.argv[1:])
72 import portage.util, portage.const
74 portage.dep._dep_check_strict = True
76 # do this _after_ 'import portage' to prevent unnecessary tracing
77 if debug and "python-trace" in portage.features:
79 portage.debug.set_trace(True)
81 if portage.settings["NOCOLOR"] in ("yes","true") or not sys.stdout.isatty():
82 portage.output.nocolor()
86 if not ebuild.endswith(".ebuild"):
87 portage.writemsg("'%s' does not end with '.ebuild'.\n" % \
88 (ebuild,), noiselevel=-1)
91 if not os.path.isabs(ebuild):
93 # Try to get the non-canonical path from the PWD evironment variable, since
94 # the canonical path returned from os.getcwd() may may be unusable in
95 # cases where the directory stucture is built from symlinks.
96 if "PWD" in os.environ and os.environ["PWD"] != mycwd and \
97 os.path.realpath(os.environ["PWD"]) == mycwd:
98 mycwd = portage.normalize_path(os.environ["PWD"])
99 ebuild = os.path.join(mycwd, ebuild)
100 ebuild = portage.normalize_path(ebuild)
101 # portdbapi uses the canonical path for the base of the portage tree, but
102 # subdirectories of the base can be built from symlinks (like crossdev does).
103 ebuild_portdir = os.path.realpath(
104 os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
105 ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
107 # Make sure that portdb.findname() returns the correct ebuild.
108 if ebuild_portdir not in portage.portdb.porttrees:
109 os.environ["PORTDIR_OVERLAY"] = \
110 os.environ.get("PORTDIR_OVERLAY","") + " " + ebuild_portdir
111 print "Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir
112 portage.close_portdbapi_caches()
114 del portage.portdb.porttrees[1:]
115 if ebuild_portdir != portage.portdb.porttree_root:
116 portage.portdb.porttrees.append(ebuild_portdir)
118 if not os.path.exists(ebuild):
119 print "'%s' does not exist." % ebuild
122 ebuild_split = ebuild.split("/")
124 cpv = "/".join(ebuild_split[-2:])[:-7]
126 if not portage.catpkgsplit(cpv):
127 print "!!! %s does not follow correct package syntax." % (cpv)
130 if ebuild.startswith(portage.root + portage.const.VDB_PATH):
133 portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)
135 if os.path.realpath(portage_ebuild) != ebuild:
136 print "!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild)
142 portage_ebuild = portage.portdb.findname(cpv)
144 if not portage_ebuild or portage_ebuild != ebuild:
145 print "!!! %s does not seem to have a valid PORTDIR structure." % ebuild
148 if len(pargs) > 1 and "config" in pargs:
149 print "config must be called on it's own, not combined with any other phase"
152 def discard_digests(myebuild, mysettings, mydbapi):
153 """Discard all distfiles digests for the given ebuild. This is useful when
154 upstream has changed the identity of the distfiles and the user would
155 otherwise have to manually remove the Manifest and files/digest-* files in
156 order to ensure correct results."""
158 portage._doebuild_manifest_exempt_depend += 1
159 pkgdir = os.path.dirname(myebuild)
160 fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
161 cat, pkg = pkgdir.split(os.sep)[-2:]
162 cpv = cat + "/" + os.path.basename(myebuild)[:-7]
163 from portage.manifest import Manifest
164 mf = Manifest(pkgdir, mysettings["DISTDIR"],
165 fetchlist_dict=fetchlist_dict, manifest1_compat=False)
166 mf.create(requiredDistfiles=None,
167 assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
168 distfiles = fetchlist_dict[cpv]
169 for myfile in distfiles:
171 del mf.fhashdict["DIST"][myfile]
176 portage._doebuild_manifest_exempt_depend -= 1
178 portage.settings.validate() # generate warning messages if necessary
179 tmpsettings = portage.config(clone=portage.settings)
180 tmpsettings["PORTAGE_VERBOSE"] = "1"
181 tmpsettings.backup_changes("PORTAGE_VERBOSE")
183 # This variable is a signal to config.regenerate() to
184 # indicate that the test phase should be enabled regardless
185 # of problems such as masked "test" USE flag.
186 tmpsettings["EBUILD_FORCE_TEST"] = "1"
187 tmpsettings.backup_changes("EBUILD_FORCE_TEST")
188 if "test" not in tmpsettings.features:
189 tmpsettings.features.append("test")
190 tmpsettings.features.sort()
191 tmpsettings["FEATURES"] = " ".join(tmpsettings.features)
192 tmpsettings.backup_changes("FEATURES")
194 if opts.skip_manifest:
195 tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
196 tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")
197 portage._doebuild_manifest_exempt_depend += 1
199 build_dir_phases = set(["setup", "unpack", "configure", "compile",
200 "test", "install", "package", "rpm"])
202 def stale_env_warning():
203 if "clean" not in pargs and \
204 "noauto" not in tmpsettings.features and \
205 tmpsettings.get("PORTAGE_QUIET") != "1" and \
206 build_dir_phases.intersection(pargs):
207 portage.doebuild_environment(ebuild, "setup", portage.root,
208 tmpsettings, debug, 1, portage.portdb)
209 env_filename = os.path.join(tmpsettings["T"], "environment")
210 if os.path.exists(env_filename):
211 msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
212 "Run 'clean' to start with a fresh environment.") % \
213 (tmpsettings["PF"], )
214 from textwrap import wrap
217 portage.writemsg(">>> %s\n" % x)
219 from portage.exception import PermissionDenied, \
220 PortagePackageException, UnsupportedAPIException
221 checked_for_stale_env = False
225 if not checked_for_stale_env and arg not in ("digest","manifest"):
226 # This has to go after manifest generation since otherwise
227 # aux_get() might fail due to invalid ebuild digests.
229 checked_for_stale_env = True
231 if arg in ("digest", "manifest") and force:
232 discard_digests(ebuild, tmpsettings, portage.portdb)
233 a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
234 debug=debug, tree=mytree)
235 except KeyboardInterrupt:
241 except UnsupportedAPIException, e:
242 from textwrap import wrap
243 msg = wrap(str(e), 70)
246 portage.writemsg("!!! %s\n" % x, noiselevel=-1)
248 except PortagePackageException, e:
249 portage.writemsg("!!! %s\n" % (e,), noiselevel=-1)
251 except PermissionDenied, e:
252 portage.writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1)
255 print "Could not run the required binary?"