2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Header: /var/cvsroot/gentoo-src/portage/bin/ebuild,v 1.18.2.3 2005/05/07 04:32:59 ferringb Exp $
10 description = "See the ebuild(1) man page for more info"
11 usage = "Usage: ebuild <ebuild file> <command> [command] ..."
12 parser = optparse.OptionParser(description=description, usage=usage)
14 force_help = "When used together with the digest or manifest " + \
15 "command, this option forces regeneration of digests for all " + \
16 "distfiles associated with the current ebuild. Any distfiles " + \
17 "that do not already exist in ${DISTDIR} will be automatically fetched."
19 parser.add_option("--force", help=force_help, action="store_true", dest="force")
20 parser.add_option("--debug", help="show debug output",
21 action="store_true", dest="debug")
22 parser.add_option("--skip-manifest", help="skip all manifest checks",
23 action="store_true", dest="skip_manifest")
25 opts, pargs = parser.parse_args(args=sys.argv[1:])
28 parser.error("missing required args")
34 print "Disabling noauto in features... merge disables it. (qmerge doesn't)"
35 os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " -noauto"
37 os.environ["PORTAGE_CALLER"]="ebuild"
41 from os import path as osp
42 sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
45 import portage.util, portage.const
47 portage.dep._dep_check_strict = True
49 # do this _after_ 'import portage' to prevent unnecessary tracing
50 if debug and "python-trace" in portage.features:
52 portage.debug.set_trace(True)
54 if portage.settings["NOCOLOR"] in ("yes","true") or not sys.stdout.isatty():
55 portage.output.nocolor()
58 if not os.path.isabs(ebuild):
60 # Try to get the non-canonical path from the PWD evironment variable, since
61 # the canonical path returned from os.getcwd() may may be unusable in
62 # cases where the directory stucture is built from symlinks.
63 if "PWD" in os.environ and os.environ["PWD"] != mycwd and \
64 os.path.realpath(os.environ["PWD"]) == mycwd:
65 mycwd = portage.normalize_path(os.environ["PWD"])
66 ebuild = os.path.join(mycwd, ebuild)
67 ebuild = portage.normalize_path(ebuild)
68 # portdbapi uses the canonical path for the base of the portage tree, but
69 # subdirectories of the base can be built from symlinks (like crossdev does).
70 ebuild_portdir = os.path.realpath(
71 os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
72 ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
74 # Make sure that portdb.findname() returns the correct ebuild.
75 if ebuild_portdir not in portage.portdb.porttrees:
76 os.environ["PORTDIR_OVERLAY"] = \
77 os.environ.get("PORTDIR_OVERLAY","") + " " + ebuild_portdir
78 print "Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir
79 portage.close_portdbapi_caches()
81 del portage.portdb.porttrees[1:]
82 if ebuild_portdir != portage.portdb.porttree_root:
83 portage.portdb.porttrees.append(ebuild_portdir)
85 if not os.path.exists(ebuild):
86 print "'%s' does not exist." % ebuild
89 ebuild_split = ebuild.split("/")
91 cpv = "/".join(ebuild_split[-2:])[:-7]
93 if not portage.catpkgsplit(cpv):
94 print "!!! %s does not follow correct package syntax." % (cpv)
97 if ebuild.startswith(portage.root + portage.const.VDB_PATH):
100 portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)
102 if os.path.realpath(portage_ebuild) != ebuild:
103 print "!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild)
109 portage_ebuild = portage.portdb.findname(cpv)
111 if not portage_ebuild or portage_ebuild != ebuild:
112 print "!!! %s does not seem to have a valid PORTDIR structure." % ebuild
115 if len(pargs) > 1 and "config" in pargs:
116 print "config must be called on it's own, not combined with any other phase"
119 def discard_digests(myebuild, mysettings, mydbapi):
120 """Discard all distfiles digests for the given ebuild. This is useful when
121 upstream has changed the identity of the distfiles and the user would
122 otherwise have to manually remove the Manifest and files/digest-* files in
123 order to ensure correct results."""
125 portage._doebuild_manifest_exempt_depend += 1
126 pkgdir = os.path.dirname(myebuild)
127 fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
128 cat, pkg = pkgdir.split(os.sep)[-2:]
129 cpv = cat + "/" + os.path.basename(myebuild)[:-7]
130 from portage.manifest import Manifest
131 mf = Manifest(pkgdir, mysettings["DISTDIR"],
132 fetchlist_dict=fetchlist_dict, manifest1_compat=False)
133 mf.create(requiredDistfiles=None,
134 assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
135 distfiles = fetchlist_dict[cpv]
136 for myfile in distfiles:
138 del mf.fhashdict["DIST"][myfile]
143 portage._doebuild_manifest_exempt_depend -= 1
145 tmpsettings = portage.config(clone=portage.settings)
147 # This variable is a signal to config.regenerate() to
148 # indicate that the test phase should be enabled regardless
149 # of problems such as masked "test" USE flag.
150 tmpsettings["EBUILD_FORCE_TEST"] = "1"
151 tmpsettings.backup_changes("EBUILD_FORCE_TEST")
152 if "test" not in tmpsettings.features:
153 tmpsettings.features.append("test")
154 tmpsettings.features.sort()
155 tmpsettings["FEATURES"] = " ".join(tmpsettings.features)
156 tmpsettings.backup_changes("FEATURES")
158 if opts.skip_manifest:
159 tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
160 tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")
161 portage._doebuild_manifest_exempt_depend += 1
163 build_dir_phases = set(["setup", "unpack", "compile",
164 "test", "install", "package", "rpm"])
166 def stale_env_warning():
167 if "clean" not in pargs and \
168 "noauto" not in tmpsettings.features and \
169 tmpsettings.get("PORTAGE_QUIET") != "1" and \
170 build_dir_phases.intersection(pargs):
171 portage.doebuild_environment(ebuild, "setup", portage.root,
172 tmpsettings, debug, 1, portage.portdb)
173 env_filename = os.path.join(tmpsettings["T"], "environment")
174 if os.path.exists(env_filename):
175 msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
176 "Run 'clean' to start with a fresh environment.") % \
177 (tmpsettings["PF"], )
178 from textwrap import wrap
181 portage.writemsg(">>> %s\n" % x)
183 from portage.exception import UnsupportedAPIException
184 checked_for_stale_env = False
188 if not checked_for_stale_env and arg not in ("digest","manifest"):
189 # This has to go after manifest generation since otherwise
190 # aux_get() might fail due to invalid ebuild digests.
192 checked_for_stale_env = True
194 if arg in ("digest", "manifest") and force:
195 discard_digests(ebuild, tmpsettings, portage.portdb)
196 a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
197 debug=debug, tree=mytree)
198 except KeyboardInterrupt:
204 except UnsupportedAPIException, e:
205 from textwrap import wrap
206 msg = wrap(str(e), 70)
209 portage.writemsg("!!! %s\n" % x, noiselevel=-1)
212 print "Could not run the required binary?"