2 # pylint: disable-msg=C0301,W0613,W0612,C0103,E0611,W0511
9 Various functions dealing with portage
23 from portage import dep as portage_dep
26 from portage import portage_dep
28 sys.path.insert(0, "/usr/lib/gentoolkit/pym")
32 __docformat__ = 'restructuredtext'
34 ENV = portage.config(clone=portage.settings).environ()
35 LOGGER = logging.getLogger(__name__)
36 LOGGER.setLevel(logging.DEBUG)
37 LOGGER.addHandler(logging.StreamHandler())
40 def get_installed_ver(cpn):
42 Return PV for installed version of package
44 @param cpn: cat/pkg-ver
47 @returns: string version or None if not pkg installed
51 #Return first version installed
52 #XXX Log warning if more than one installed (SLOT)?
53 pkg = gentoolkit.find_installed_packages(cpn, masked=True)[0]
54 return pkg.get_version()
60 Return True if cpn is valid portage category/pn-pv
62 @param cpn: cat/pkg-ver
65 @returns: True if installed, False if not installed
67 if portage_dep.isvalidatom(cpn):
73 def ebuild_exists(cat_pkg):
76 Checks if an ebuild exists in portage tree or overlay
78 @param cat_pkg: portage category/packagename
81 @returns: True if ebuild exists, False if no ebuild exists
84 pkgs = gentoolkit.find_packages(cat_pkg)
90 #def run_tests(ebuild_path):
92 # Use portage to run tests
94 # Some day I'll figure out how to get portage to do this directly. Some day.
96 # @param ebuild_path: full path to ebuild
97 # @type ebuild_path: string
98 # @returns: None if succeed, raises OSError if fails to unpack
101 # cmd = "/usr/bin/python /usr/bin/ebuild %s test" % ebuild_path
103 # (status, output) = commands.getstatusoutput(cmd)
107 def unpack_ebuild(ebuild_path):
109 Use portage to unpack an ebuild
111 Some day I'll figure out how to get portage to do this directly. Some day.
113 @param ebuild_path: full path to ebuild
114 @type ebuild_path: string
115 @returns: None if succeed, raises OSError if fails to unpack
118 (status, output) = commands.getstatusoutput("ebuild %s digest setup clean unpack" % ebuild_path)
120 #Portage's error message, sometimes.
121 #Couldn't determine PN or PV so we misnamed ebuild
122 if 'does not follow correct package syntax' in output:
124 LOGGER.error("Misnamed ebuild: %s" % ebuild_path)
125 LOGGER.error("Try using -n or -v to force PN or PV")
126 os.unlink(ebuild_path)
131 def find_s_dir(p, cat):
133 Try to get ${S} by determining what directories were unpacked
135 @param p: portage ${P}
138 @param cat: valid portage category
141 @returns: string with directory name if detected, empty string
142 if S=WORKDIR, None if couldn't find S
147 workdir = get_workdir(p, cat)
148 files = os.listdir(workdir)
150 for unpacked in files:
151 if os.path.isdir(os.path.join(workdir, unpacked)):
152 dirs.append(unpacked)
154 #Only one directory, must be it.
160 #XXX Need to search whole tree for setup.py
161 LOGGER.error("Can't determine ${S}")
162 LOGGER.error("Unpacked multiple directories: %s" % dirs)
164 def get_workdir(p, cat):
168 @param p: portage ${P}
171 @param cat: valid portage category
174 @return: string of portage_tmpdir/cp
177 return '%s/portage/%s/%s/work' % (get_portage_tmpdir(), cat, p)
179 def get_portdir_overlay():
180 """Return PORTDIR_OVERLAY from /etc/make.conf"""
181 return ENV['PORTDIR_OVERLAY'].split(" ")[0]
183 def get_portage_tmpdir():
184 """Return PORTAGE_TMPDIR from /etc/make.conf"""
185 return ENV["PORTAGE_TMPDIR"]
188 """Return PORTDIR from /etc/make.conf"""
189 return ENV["PORTDIR"]
192 """Return first ACCEPT_KEYWORDS from /etc/make.conf"""
193 #Choose the first arch they have, in case of multiples.
196 arch = ENV["ACCEPT_KEYWORDS"].split(' ')[0]
198 LOGGER.error("No ACCEPT_KEYWORDS found, using ~x86")
201 #New ebuilds must be ~arch
203 if not arch.startswith('~'):
207 def make_overlay_dir(category, pn, overlay):
209 Create directory(s) in overlay for ebuild
211 @param category: valid portage category
212 @type category: string
214 @param pn: portage ${PN}
217 @param overlay: portage overlay directory
218 @type overlay: string
220 @return: string of full directory name
224 ebuild_dir = os.path.join(overlay, category, pn)
225 if not os.path.isdir(ebuild_dir):
227 os.makedirs(ebuild_dir)
235 def find_egg_info_dir(root):
237 Locate all files matching supplied filename pattern in and below
238 supplied root directory.
240 for path, dirs, files in os.walk(os.path.abspath(root)):
241 for this_dir in dirs:
242 if this_dir.endswith(".egg-info"):
243 return os.path.normpath(os.path.join(path, this_dir, ".."))
245 #Unused as of now. Could be used to find setup.py
246 #def find_files(pattern, root):
248 # Locate all files matching supplied filename pattern in and below
249 # supplied root directory.
251 # for path, dirs, files in os.walk(os.path.abspath(root)):
252 # for filename in fnmatch.filter(dirs, pattern):
253 # yield os.path.join(path, filename)