164 lines
5.1 KiB
Python
164 lines
5.1 KiB
Python
from os import listdir
|
|
from os.path import abspath, isfile, dirname
|
|
from portage.versions import cpv_sort_key
|
|
from configparser import ConfigParser
|
|
import xml.etree.ElementTree as ET
|
|
|
|
class ebuild:
|
|
|
|
def __init__(self, package, full_name):
|
|
self.package = package
|
|
self.path = package.path+'/'+full_name+'.ebuild'
|
|
self.name = '-'.join(full_name.split('-')[0:-1])
|
|
self.version = full_name.split('-')[-1]
|
|
self.live = self.version[:4] == '9999'
|
|
self.inherits = []
|
|
self.vars = {}
|
|
self.loaded = False
|
|
|
|
def load(self):
|
|
# TODO: Read ebuilds properly
|
|
with open(self.path, 'r') as fp:
|
|
for line in fp.readlines():
|
|
line = line[:-1].split('#', maxsplit=1)[0]
|
|
if len(line) > 0 and '=' in line:
|
|
s = [p.strip() for p in line.split('=', maxsplit=1)]
|
|
if len(s[1]) > 1 and s[1][0] == s[1][-1] == '"':
|
|
self.vars[s[0]] = s[1][1:-1]
|
|
if line.startswith('inherit'):
|
|
self.inherits.extend(line.split(' ')[1:])
|
|
if len(line) > 0 and line[-1] == '{':
|
|
break
|
|
self.loaded = True
|
|
|
|
class manifest:
|
|
def __init__(self, path):
|
|
self.path = path
|
|
self.loaded = False
|
|
|
|
def load(self):
|
|
with open(self.path, 'r') as fp:
|
|
self.entries = [n[:-1].split(' ') for n in fp.readlines()]
|
|
self.loaded = True
|
|
|
|
class metadata:
|
|
def __init__(self, path):
|
|
self.path = path
|
|
self.maintainers = []
|
|
self.remotes = []
|
|
self.loaded = False
|
|
|
|
def load(self):
|
|
self.tree = ET.parse(self.path)
|
|
self.root = self.tree.getroot()
|
|
for maintainer in self.root.findall('./maintainer'):
|
|
self.maintainers.append(maintainer.find('email').text)
|
|
for upstream in self.root.findall('./upstream'):
|
|
remote = upstream.find('remote-id')
|
|
if remote is not None:
|
|
self.remotes.append([remote.get('type'), remote.text])
|
|
self.loaded = True
|
|
|
|
class package:
|
|
def __init__(self, category, name):
|
|
self.category = category
|
|
self.name = name
|
|
self.path = category.path+'/'+name
|
|
self.ebuilds = []
|
|
self.loaded = False
|
|
|
|
@classmethod
|
|
def from_path(self, path):
|
|
path = abspath(path)
|
|
if path[-1] == '/':
|
|
path = path[:-1]
|
|
cat = category.from_path(dirname(path))
|
|
return package(cat, path.split('/')[-1])
|
|
|
|
def load(self):
|
|
self.full_name = self.category.name+'/'+self.name+'::'+self.category.repo.name
|
|
ls = listdir(self.path)
|
|
if 'Manifest' in ls:
|
|
mf = manifest(self.path+'/Manifest')
|
|
mf.load()
|
|
self.manifest = mf
|
|
if 'metadata.xml' in ls:
|
|
md = metadata(self.path+'/metadata.xml')
|
|
md.load()
|
|
self.metadata = md
|
|
ebuild_names = [n[:-7] for n in filter(lambda name: name[-7:] == '.ebuild', ls)]
|
|
ebuild_names = sorted(ebuild_names, key=cpv_sort_key())[::-1]
|
|
for name in ebuild_names:
|
|
eb = ebuild(self, name)
|
|
eb.load()
|
|
self.ebuilds.append(eb)
|
|
self.loaded = True
|
|
|
|
def version_latest(self):
|
|
for eb in self.ebuilds:
|
|
if not eb.live:
|
|
return eb.version
|
|
return None
|
|
|
|
class category:
|
|
def __init__(self, repo, name):
|
|
self.repo = repo
|
|
self.name = name
|
|
self.path = repo.path+'/'+name
|
|
self.packages = {}
|
|
self.loaded = False
|
|
|
|
@classmethod
|
|
def from_path(self, path):
|
|
path = abspath(path)
|
|
if path[-1] == '/':
|
|
path = path[:-1]
|
|
repo = repository(dirname(path))
|
|
return category(repo, path.split('/')[-1])
|
|
|
|
def load(self):
|
|
for name in listdir(self.path):
|
|
if isfile(self.path+'/'+name):
|
|
continue
|
|
self.packages[name] = package(self, name)
|
|
self.loaded = True
|
|
|
|
class repository:
|
|
def __init__(self, path):
|
|
self.path = abspath(path)
|
|
self.categories = {}
|
|
with open(self.path+'/profiles/repo_name', 'r') as fp:
|
|
self.name = fp.read().replace("\n", '')
|
|
self.loaded = False
|
|
|
|
def load(self):
|
|
for name in listdir(self.path):
|
|
if '-' not in name or isfile(self.path+'/'+name):
|
|
continue
|
|
self.categories[name] = category(self, name)
|
|
self.loaded = True
|
|
|
|
class repos:
|
|
def __init__(self):
|
|
self.from_path('/etc/portage/repos.conf')
|
|
self.loaded = False
|
|
|
|
@classmethod
|
|
def from_path(self, path):
|
|
self.path = abspath(path)
|
|
self.repos = {}
|
|
|
|
def load(self):
|
|
conf_paths = []
|
|
if isfile(self.path):
|
|
conf_paths.append(self.path)
|
|
else:
|
|
for name in listdir(self.path):
|
|
if name[-5:] == '.conf':
|
|
conf_paths.append(self.path+'/'+name)
|
|
conf = ConfigParser()
|
|
conf.read(conf_paths)
|
|
for section in conf.sections():
|
|
self.repos[section] = repository(conf[section]['location'])
|
|
self.loaded = True
|