Namespace sanitizing, step 4
[portage.git] / bin / ebuild
1 #!/usr/bin/python -O
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 $
5
6 import getopt, os, sys
7
8 if len(sys.argv) <= 2:
9         print "Usage: ebuild <ebuild file> <command> [command] ..."
10         print ""
11         print "See the ebuild(1) man page for more info"
12         sys.exit(1)
13
14
15 opts, pargs = getopt.getopt(sys.argv[1:], '', ['debug', 'force'])
16 debug = ("--debug",'') in opts
17 force = ("--force",'') in opts
18
19 if "merge" in pargs:
20         print "Disabling noauto in features... merge disables it. (qmerge doesn't)"
21         os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " -noauto"
22
23 os.environ["PORTAGE_CALLER"]="ebuild"
24 try:
25         import portage
26 except ImportError:
27         sys.path.insert(0, "/usr/lib/portage/pym")
28         import portage
29
30 import portage.util, portage.const
31
32 # do this _after_ 'import portage' to prevent unnecessary tracing
33 if debug and "python-trace" in portage.features:
34         import portage.debug
35         portage.debug.set_trace(True)
36
37 if portage.settings["NOCOLOR"] in ("yes","true") or not sys.stdout.isatty():
38         import output
39         portage.output.nocolor()
40
41 ebuild = pargs.pop(0)
42 if not os.path.isabs(ebuild):
43         mycwd = os.getcwd()
44         # Try to get the non-canonical path from the PWD evironment variable, since
45         # the canonical path returned from os.getcwd() may may be unusable in
46         # cases where the directory stucture is built from symlinks.
47         if "PWD" in os.environ and os.environ["PWD"] != mycwd and \
48                 os.path.realpath(os.environ["PWD"]) == mycwd:
49                 mycwd = portage.normalize_path(os.environ["PWD"])
50         ebuild = os.path.join(mycwd, ebuild)
51 ebuild = portage.normalize_path(ebuild)
52 # portdbapi uses the canonical path for the base of the portage tree, but
53 # subdirectories of the base can be built from symlinks (like crossdev does).
54 ebuild_portdir = os.path.realpath(os.path.dirname(os.path.dirname(ebuild)))
55 ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-2:])
56
57 if not os.path.exists(ebuild):
58         print "'%s' does not exist." % ebuild
59         sys.exit(1)
60
61 ebuild_split = ebuild.split("/")
62 del ebuild_split[-2]
63 cpv = "/".join(ebuild_split[-2:])[:-7]
64
65 if not portage.catpkgsplit(cpv):
66         print "!!! %s does not follow correct package syntax." % (cpv)
67         sys.exit(1)
68
69 if ebuild.startswith(portage.root + portage.const.VDB_PATH):
70         mytree = "vartree"
71
72         portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)
73
74         if os.path.realpath(portage_ebuild) != ebuild:
75                 print "!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild)
76                 sys.exit(1)
77
78 else:
79         mytree = "porttree"
80
81         portage_ebuild = portage.portdb.findname(cpv)
82
83         if not portage_ebuild or portage_ebuild != ebuild:
84                 overlay = "/".join(ebuild_split[:-2])
85                 os.environ["PORTDIR_OVERLAY"] = os.environ.get("PORTDIR_OVERLAY","") + " " + overlay
86                 print "Appending %s to PORTDIR_OVERLAY..." % overlay
87                 portage.close_portdbapi_caches()
88                 reload(portage)
89                 portage_ebuild = portage.portdb.findname(cpv)
90
91                 if not portage_ebuild or portage_ebuild != ebuild:
92                         print "!!! %s does not seem to have a valid PORTDIR structure." % overlay
93                         sys.exit(1)
94
95
96 if len(pargs) > 1 and "config" in pargs:
97         print "config must be called on it's own, not combined with any other phase"
98         sys.exit(1)
99
100 def discard_digests(myebuild, mysettings, mydbapi):
101         """Discard all distfiles digests for the given ebuild.  This is useful when
102         upstream has changed the identity of the distfiles and the user would
103         otherwise have to manually remove the Manifest and files/digest-* files in
104         order to ensure correct results."""
105         try:
106                 portage._doebuild_manifest_exempt_depend += 1
107                 pkgdir = os.path.dirname(myebuild)
108                 fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
109                 cat, pkg = pkgdir.split(os.sep)[-2:]
110                 cpv = cat + "/" + os.path.basename(myebuild)[:-7]
111                 from portage.manifest import Manifest
112                 mf = Manifest(pkgdir, mysettings["DISTDIR"],
113                         fetchlist_dict=fetchlist_dict)
114                 mf.create(requiredDistfiles=None,
115                         assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
116                 distfiles = fetchlist_dict[cpv]
117                 for myfile in distfiles:
118                         try:
119                                 del mf.fhashdict["DIST"][myfile]
120                         except KeyError:
121                                 pass
122                 mf.write()
123         finally:
124                 portage._doebuild_manifest_exempt_depend -= 1
125
126 for arg in pargs:
127         try:
128                 tmpsettings = portage.config(clone=portage.settings)
129                 if arg == "test" and not "test" in tmpsettings.features:
130                         print "Forcing test."
131                         tmpsettings["EBUILD_FORCE_TEST"] = "1"
132                         tmpsettings.backupenv["EBUILD_FORCE_TEST"] = "1"
133                 if arg == "digest" and force:
134                         discard_digests(ebuild, tmpsettings, portage.portdb)
135                 a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
136                         debug=debug, tree=mytree)
137         except KeyboardInterrupt:
138                 print "Interrupted."
139                 a = 1
140         except KeyError:
141                 # aux_get error
142                 a = 1
143         if a == None:
144                 print "Could not run the required binary?"
145                 a = 127
146         if a:
147                 sys.exit(a)