1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
import re, os
from ebuild import *
from filetricks import *
from settings import *
#figure out the location of the portage tree, or return it if we already know it
portage_location=None
def portage_dir():
global portage_location
if portage_location!=None: #we already know
return portage_location
if os.path.exists('/etc/paludis/repositories/gentoo.conf'): #paludis stores repository data here
conffile=open('/etc/paludis/repositories/gentoo.conf')
for line in conffile:
if 'location'==line[:len('location')]:
portage_location=re.sub('\$\{.+?\}','',line[line.find('=')+1:]).strip() #remove ${ROOT} and other variables (lucky guess, lol)
elif os.path.exists('/etc/make.conf'): #portage stores portage location here
conffile=open('/etc/make.conf')
for line in conffile:
if 'PORTDIR' in line and '=' in line:
portage_location=re.sub('\"(.*)\"','\1',line[line.find('='):]).strip()
elif os.path.exists('/usr/portage'): #default location
portage_location='/usr/portage'
else:
raise RuntimeError('Could not deduce portage location')
return portage_location
def pmsify_license_field(license_list):
portdir=portage_dir()
available_licenses=os.listdir(os.path.join(portdir,'licenses'))
#note: the following returns a list of tuples
matches=re.findall(r'\s*([^|]+)\s*',license_list) #split into licenses + versions
licenses=[]
for license_part in matches: #process each license option
if license_part[:4]=='file': #license field referse to a file
#licenses.append(license_part) #we'll have to somehow install this file...
continue
parse=re.match(r'(.+)\(\W*([^()]+?)\)',license_part)
try_license=None
if parse: #versioned license
license_name=parse.group(1).strip()
version=parse.group(2).strip()
try_license=license_name+'-'+version
else: #perhaps we just want version 1?
try_license=license_part+'-1'
for license in available_licenses:
if license==license_part or try_license==license:
licenses.append(license)
break
else:
licenses.append('as-is') #unknown
return licenses
def pmsify_package_name(name):
if len(name)==0:
return 'test'
name=re.sub('[^a-zA-Z0-9+_-]','',name) #name may only contain these characters
if not re.match('[a-zA-Z0-9+_].*',name): #package name must start with [a-zA-Z0-9+_]
name='_'+name
if re.match('.*-[0-9]+',name): #package name may not end in hyphen followed by integer
name=name+'_'
return name
def pmsify_package_version(version_str):
return version_str.replace('-','.') #some CRAN-style versions have the form 0.1-1, which we transform into 0.1.1
def pmsify_package_list(package_list):
#note: the following returns a list of tuples
matches=re.findall(r'\s*(([^,]+\([^()]+?\))|([^,]+))\s*',package_list) #split into packages + versions
packages=[]
for package_part in matches: #process each package match
if len(package_part[1])>len(package_part[2]): #versioned package identifier
parse=re.match(r'([^,]+)\(([^()]+?)\)',package_part[1])
pkg_name=parse.group(1).strip()
versions=parse.group(2)
#fixme version specifiers
if pkg_name=='R':
category='dev-lang'
else:
category='dev-R'
packages.append(category+'/'+pkg_name)
else:
pkg_name=package_part[2].strip()
if pkg_name=='R':
category='dev-lang'
else:
category='dev-R' #assume it's a CRAN package
packages.append(category+'/'+pkg_name)
return packages
#Parse package options into values we can work with in accordance with PMS
def pmsify_package_data(data,remote_repository):
pms_pkg=Ebuild()
pms_pkg.cran_data=data
e_vars=pms_pkg.ebuild_vars
#fix settings:
e_vars['pn']=pmsify_package_name(data['package'])
if 'version' not in data: #set a version even if we have none
e_vars['pv']='0'
else:
e_vars['pv']=pmsify_package_version(data['version'])
if 'depends' in data:
deps=pmsify_package_list(data['depends'])
else: #some packages don't set dependencies, so force dependency on R
deps=['dev-lang/R',]
e_vars['depend']=deps
e_vars['pdepend']=deps
e_vars['rdepend']=deps
e_vars['iuse']="doc"
e_vars['keywords']="~x86 ~amd64"
if 'description' in data:
e_vars['description']=data['description'].strip().replace('\n',' ')
else:
e_vars['description']=e_vars['pn']
if 'license' in data: #fixme parse license data
e_vars['license']=pmsify_license_field(data['license'])
e_vars['src_uri']=remote_repository+'/src/contrib/'+data['package']+'_'+data['version']+'.tar.gz'
return pms_pkg
def read_packages(package_filename,local_repository):
packages_file=open(package_filename,"r")
file_parts=EmptyLinesFile(packages_file) #this is where we split the PACKAGES file into several file parts
packages=[]
import rfc822
repository_file=open(os.path.join(local_repository,REPO_MYDIR,'remote_uri'),'r')
remote_uri=repository_file.read().strip()
while not file_parts.eof:
cran_package=dict(rfc822.Message(file_parts).items()) #read part of PACKAGES file
pms_package=pmsify_package_data(cran_package,remote_uri) #fix values
packages.append(pms_package) #store in dict
return packages
def find_package(repo_location,package_name):
packages=read_packages(os.path.join(repo_location,REPO_MYDIR,'PACKAGES'),repo_location)
for package in packages:
if package.ebuild_vars['pn']==package_name:
return package
raise ValueError("Package not found")
|