Newer
Older

Nathan Hertz
committed
import setuptools, importlib, subprocess, os, re

Nathan Hertz
committed
def write_metafile(metadata, filename):
try:
os.makedirs(filename[:-10])
except FileExistsError:

Nathan Hertz
committed
pass

Nathan Hertz
committed
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
with open(filename, 'w') as f:
f.write(metadata)
def generate_metafile(setup_dict, path):
metadata = (
'{{% set name = "{name}" %}}\n'
'{{% set version = "{version}" %}}\n'
'\n'
'package:\n'
' name: "{{{{ name|lower }}}}"\n'
' version: "{{{{ version }}}}"\n'
'\n'
'build:\n'
).format(
name=setup_dict["name"],
version=setup_dict["version"]
)
if 'entry_points' in setup_dict.keys():
metadata += ' entry_points:\n'
for ep in setup_dict['entry_points']:
metadata += ' - {}\n'.format(ep)
metadata += (' script: {{{{PYTHON}}}} setup.py install\n'
'\n'
'source:\n'
' path: {}\n'.format(path))
metadata += '\n'
if 'install_requires' in setup_dict.keys():
metadata += 'requirements:\n'
build_reqs = ' build:\n'
run_reqs = ' run:\n'
for req in setup_dict['install_requires'].split(', '):
build_reqs += ' - {}\n'.format(req)
run_reqs += ' - {}\n'.format(req)
metadata += build_reqs
metadata += run_reqs
if 'tests_require' in setup_dict.keys():
metadata += ('test:\n'
' source_files:\n'
' - test/\n'
' requires:\n')
for req in setup_dict['tests_require'].split(', '):
metadata += ' - {}\n'.format(req)
metadata += (' commands:\n'
' - pytest -vv --log-level=DEBUG --showlocals\n')
metadata += ('\n'
'about:\n'
' license: "{0}"\n'
' license_family: "{0}"\n'
' summary: "{1}"'.format(setup_dict['license'], setup_dict['description']))
return metadata

Nathan Hertz
committed
def data_to_dict(setup_data):
data_dict = {}
r_entry = r"([a-z-_]+): "
r_id = r"[a-zA-Z0-9-_]"

Nathan Hertz
committed
r_ep = r"{{(?:[a-zA-Z0-9-_.]+):\s*(?P<values>(?:{0}+\s*=\s*[a-zA-Z0-9-_.]+:{0}+(?:,\s*)?)*)}}".format(r_id)

Nathan Hertz
committed
for d in setup_data:
result = re.match(r_entry, d)
if result:
substrings = [result.group(0), '[', ']', '\'', '"']
field = result.group(1)
value = del_substrings(d, substrings)
if value == "None":
continue
if re.match(r_ep, value):
# Parse entry points
value = re.match(r_ep, value).group('values')
value = re.split(',\s*', value)
data_dict[field] = value

Nathan Hertz
committed
# print("{}: {}".format(field, value))

Nathan Hertz
committed
return data_dict

Nathan Hertz
committed
def get_outputs(names):
outputs = []
for name in names:
outputs.append("support/conda/{}/meta.yaml".format(name))
return outputs

Nathan Hertz
committed
def get_dirs():
find = subprocess.run(['find', '.', '-name', 'setup.py'], stdout=subprocess.PIPE)
dirs = find.stdout.decode('utf-8').split('\n')
for i, d in enumerate(dirs):
if d.find("./src") >= 0:
dirs.remove(d)
continue
dirs[i] = d.replace('/setup.py', '')
return dirs
def get_names(dirs):
names = []
for d in dirs:
if d != '':

Nathan Hertz
committed
name = d.split('/')[-1]
if name == "archive":
# Case with ./services/archive having special dir structure
name = "services"
names.append(name)

Nathan Hertz
committed
return names
def del_substrings(s, substrings):
for replace in substrings:
s = s.replace(replace, '')
return s
class Recipe:
def __init__(self, buildout, name, options):
self.dirs = get_dirs()
self.names = get_names(self.dirs)

Nathan Hertz
committed
self.outputs = get_outputs(self.names)

Nathan Hertz
committed
self.options = options

Nathan Hertz
committed
# TODO: Keep track of path in setup_dict

Nathan Hertz
committed
def install(self):
root = os.getcwd()

Nathan Hertz
committed
for i, d in enumerate(self.dirs):

Nathan Hertz
committed
if d != '':
os.chdir(d)
proc = subprocess.run(['python3', 'parse_setup.py'], stdout=subprocess.PIPE)
os.chdir(root)
setup_data = (proc.stdout.decode('utf-8')).split('\n')
data_dict = data_to_dict(setup_data)

Nathan Hertz
committed
metadata = generate_metafile(data_dict, d)
write_metafile(metadata, self.outputs[i])
self.options.created(self.outputs[i])

Nathan Hertz
committed
return self.options.created()
update = install