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.add("test")
190 tmpsettings["FEATURES"] = " ".join(sorted(tmpsettings.features))
191 tmpsettings.backup_changes("FEATURES")
193 if opts.skip_manifest:
194 tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
195 tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")
196 portage._doebuild_manifest_exempt_depend += 1
198 build_dir_phases = set(["setup", "unpack", "prepare", "configure", "compile",
199 "test", "install", "package", "rpm"])
201 def stale_env_warning():
202 if "clean" not in pargs and \
203 "noauto" not in tmpsettings.features and \
204 tmpsettings.get("PORTAGE_QUIET") != "1" and \
205 build_dir_phases.intersection(pargs):
206 portage.doebuild_environment(ebuild, "setup", portage.root,
207 tmpsettings, debug, 1, portage.portdb)
208 env_filename = os.path.join(tmpsettings["T"], "environment")
209 if os.path.exists(env_filename):
210 msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
211 "Run 'clean' to start with a fresh environment.") % \
212 (tmpsettings["PF"], )
213 from textwrap import wrap
216 portage.writemsg(">>> %s\n" % x)
218 from portage.exception import PermissionDenied, \
219 PortagePackageException, UnsupportedAPIException
220 checked_for_stale_env = False
224 if not checked_for_stale_env and arg not in ("digest","manifest"):
225 # This has to go after manifest generation since otherwise
226 # aux_get() might fail due to invalid ebuild digests.
228 checked_for_stale_env = True
230 if arg in ("digest", "manifest") and force:
231 discard_digests(ebuild, tmpsettings, portage.portdb)
232 a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
233 debug=debug, tree=mytree)
234 except KeyboardInterrupt:
240 except UnsupportedAPIException, e:
241 from textwrap import wrap
242 msg = wrap(str(e), 70)
245 portage.writemsg("!!! %s\n" % x, noiselevel=-1)
247 except PortagePackageException, e:
248 portage.writemsg("!!! %s\n" % (e,), noiselevel=-1)
250 except PermissionDenied, e:
251 portage.writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1)
254 print "Could not run the required binary?"