more work on parsing
This commit is contained in:
parent
24ff4c430e
commit
90b89354db
@ -12,3 +12,35 @@ def extract_list(config, section):
|
|||||||
else:
|
else:
|
||||||
l.append(x[section])
|
l.append(x[section])
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
|
||||||
|
def to_d(l):
|
||||||
|
"""
|
||||||
|
Converts list of dicts to dict.
|
||||||
|
"""
|
||||||
|
_d = {}
|
||||||
|
for x in l:
|
||||||
|
for k, v in x.items():
|
||||||
|
_d[k] = v
|
||||||
|
return _d
|
||||||
|
|
||||||
|
|
||||||
|
def test_to_d():
|
||||||
|
l = [{'a': 'b'}, {'c': 'd'}]
|
||||||
|
d = {'a': 'b', 'c': 'd'}
|
||||||
|
assert to_d(l) == d
|
||||||
|
|
||||||
|
|
||||||
|
def to_l(x):
|
||||||
|
"""
|
||||||
|
Converts list of dicts to dict.
|
||||||
|
"""
|
||||||
|
if isinstance(x, str):
|
||||||
|
return [x]
|
||||||
|
else:
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
def test_to_l():
|
||||||
|
assert to_l('foo') == ['foo']
|
||||||
|
assert to_l(['foo', 'bar']) == ['foo', 'bar']
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
def parse_cmake_module(s_in, override={}):
|
def parse_cmake_module(s_in, overrides={}):
|
||||||
import sys
|
import sys
|
||||||
from collections import Mapping, Iterable, defaultdict
|
from collections import Mapping, Iterable, defaultdict
|
||||||
from autocmake.parse_yaml import parse_yaml
|
from autocmake.parse_yaml import parse_yaml
|
||||||
@ -33,7 +33,7 @@ def parse_cmake_module(s_in, override={}):
|
|||||||
autocmake_entry = autocmake_entry.replace('\n ', '\n')
|
autocmake_entry = autocmake_entry.replace('\n ', '\n')
|
||||||
|
|
||||||
buf = StringIO(autocmake_entry)
|
buf = StringIO(autocmake_entry)
|
||||||
config = parse_yaml(buf, override)
|
config = parse_yaml(buf, overrides)
|
||||||
|
|
||||||
for k, v in config.items():
|
for k, v in config.items():
|
||||||
if isinstance(v, Iterable) and not isinstance(v, str):
|
if isinstance(v, Iterable) and not isinstance(v, str):
|
||||||
@ -109,7 +109,7 @@ enable_language(CXX)'''
|
|||||||
assert parsed_config['c'] == ['v3']
|
assert parsed_config['c'] == ['v3']
|
||||||
|
|
||||||
|
|
||||||
def test_parse_cmake_module_override():
|
def test_parse_cmake_module_overrides():
|
||||||
|
|
||||||
s = r'''#.rst:
|
s = r'''#.rst:
|
||||||
#
|
#
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
def parse_yaml(stream, override={}):
|
def parse_yaml(stream, overrides={}):
|
||||||
import yaml
|
import yaml
|
||||||
import sys
|
import sys
|
||||||
from autocmake.interpolate import interpolate
|
from autocmake.interpolate import interpolate
|
||||||
@ -10,8 +10,8 @@ def parse_yaml(stream, override={}):
|
|||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
for k in config:
|
for k in config:
|
||||||
if k in override:
|
if k in overrides:
|
||||||
config[k] = override[k]
|
config[k] = overrides[k]
|
||||||
|
|
||||||
config = interpolate(config, config)
|
config = interpolate(config, config)
|
||||||
return config
|
return config
|
||||||
|
168
update.py
168
update.py
@ -11,110 +11,99 @@ def print_progress_bar(text, done, total, width):
|
|||||||
"""
|
"""
|
||||||
Print progress bar.
|
Print progress bar.
|
||||||
"""
|
"""
|
||||||
n = int(float(width) * float(done) / float(total))
|
if total > 0:
|
||||||
sys.stdout.write("\r{0} [{1}{2}] ({3}/{4})".format(text, '#' * n, ' ' * (width - n), done, total))
|
n = int(float(width) * float(done) / float(total))
|
||||||
sys.stdout.flush()
|
sys.stdout.write("\r{0} [{1}{2}] ({3}/{4})".format(text, '#' * n, ' ' * (width - n), done, total))
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
def prepend_or_set(config, section, option, value, defaults):
|
def flat_add(l, x):
|
||||||
"""
|
if isinstance(x, str):
|
||||||
If option is already set, then value is prepended.
|
l.append(x)
|
||||||
If option is not set, then it is created and set to value.
|
return l
|
||||||
This is used to prepend options with values which come from the module documentation.
|
else:
|
||||||
"""
|
return l + x
|
||||||
if value:
|
|
||||||
if config.has_option(section, option):
|
|
||||||
value += '\n{0}'.format(config.get(section, option, 0, defaults))
|
|
||||||
config.set(section, option, value)
|
|
||||||
return config
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_modules(config, relative_path):
|
def fetch_modules(config, relative_path, download_directory):
|
||||||
"""
|
"""
|
||||||
Assemble modules which will
|
Assemble modules which will
|
||||||
be included in CMakeLists.txt.
|
be included in CMakeLists.txt.
|
||||||
"""
|
"""
|
||||||
from collections import Iterable, namedtuple
|
from collections import Iterable, namedtuple, defaultdict
|
||||||
from autocmake.extract import extract_list
|
from autocmake.extract import extract_list, to_d, to_l
|
||||||
|
from autocmake.parse_rst import parse_cmake_module
|
||||||
|
|
||||||
download_directory = 'downloaded'
|
cleaned_config = defaultdict(lambda: [])
|
||||||
if not os.path.exists(download_directory):
|
|
||||||
os.makedirs(download_directory)
|
|
||||||
|
|
||||||
# here we get the list of sources to fetch
|
|
||||||
sources = extract_list(config, 'source')
|
|
||||||
|
|
||||||
modules = []
|
modules = []
|
||||||
Module = namedtuple('Module', 'path name')
|
Module = namedtuple('Module', 'path name')
|
||||||
|
|
||||||
warnings = []
|
num_sources = len(extract_list(config, 'source'))
|
||||||
|
|
||||||
if len(sources) > 0: # otherwise division by zero in print_progress_bar
|
print_progress_bar(text='- assembling modules:',
|
||||||
print_progress_bar(text='- assembling modules:', done=0, total=len(sources), width=30)
|
done=0,
|
||||||
for i, src in enumerate(sources):
|
total=num_sources,
|
||||||
module_name = os.path.basename(src)
|
width=30)
|
||||||
if 'http' in src:
|
|
||||||
path = download_directory
|
i = 0
|
||||||
name = 'autocmake_{0}'.format(module_name)
|
for t in config['modules']:
|
||||||
dst = os.path.join(download_directory, 'autocmake_{0}'.format(module_name))
|
for k, v in t.items():
|
||||||
fetch_url(src, dst)
|
|
||||||
file_name = dst
|
i += 1
|
||||||
fetch_dst_directory = download_directory
|
d = to_d(v)
|
||||||
else:
|
for _k, _v in to_d(v).items():
|
||||||
if os.path.exists(src):
|
cleaned_config[_k] = flat_add(cleaned_config[_k], _v)
|
||||||
path = os.path.dirname(src)
|
|
||||||
name = module_name
|
# fetch sources and parse them
|
||||||
file_name = src
|
for src in to_l(d['source']):
|
||||||
fetch_dst_directory = path
|
|
||||||
|
# we download the file
|
||||||
|
module_name = os.path.basename(src)
|
||||||
|
if 'http' in src:
|
||||||
|
path = download_directory
|
||||||
|
name = 'autocmake_{0}'.format(module_name)
|
||||||
|
dst = os.path.join(download_directory, 'autocmake_{0}'.format(module_name))
|
||||||
|
fetch_url(src, dst)
|
||||||
|
file_name = dst
|
||||||
|
fetch_dst_directory = download_directory
|
||||||
else:
|
else:
|
||||||
sys.stderr.write("ERROR: {0} does not exist\n".format(src))
|
if os.path.exists(src):
|
||||||
sys.exit(-1)
|
path = os.path.dirname(src)
|
||||||
|
name = module_name
|
||||||
|
file_name = src
|
||||||
|
fetch_dst_directory = path
|
||||||
|
else:
|
||||||
|
sys.stderr.write("ERROR: {0} does not exist\n".format(src))
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
# FIXME
|
# we infer config from the module documentation
|
||||||
# if config.has_option(section, 'override'):
|
# dictionary d overrides the configuration in the module documentation
|
||||||
# defaults = ast.literal_eval(config.get(section, 'override'))
|
# this allows to override interpolation inside the module
|
||||||
# else:
|
with open(file_name, 'r') as f:
|
||||||
# defaults = {}
|
parsed_config = parse_cmake_module(f.read(), d)
|
||||||
|
for _k2, _v2 in parsed_config.items():
|
||||||
|
if _k2 not in to_d(v):
|
||||||
|
# we add to clean_config only if the entry does not exist
|
||||||
|
# in parent autocmake.yml already
|
||||||
|
# this allows to override
|
||||||
|
cleaned_config[_k2] = flat_add(cleaned_config[_k2], _v2)
|
||||||
|
|
||||||
# FIXME
|
modules.append(Module(path=path, name=name))
|
||||||
# # we infer config from the module documentation
|
print_progress_bar(text='- assembling modules:',
|
||||||
# with open(file_name, 'r') as f:
|
done=i,
|
||||||
# parsed_config = parse_cmake_module(f.read(), defaults)
|
total=num_sources,
|
||||||
# if parsed_config['warning']:
|
width=30)
|
||||||
# warnings.append('WARNING from {0}: {1}'.format(module_name, parsed_config['warning']))
|
|
||||||
# config = prepend_or_set(config, section, 'docopt', parsed_config['docopt'], defaults)
|
|
||||||
# config = prepend_or_set(config, section, 'define', parsed_config['define'], defaults)
|
|
||||||
# config = prepend_or_set(config, section, 'export', parsed_config['export'], defaults)
|
|
||||||
# if parsed_config['fetch']:
|
|
||||||
# for src in parsed_config['fetch'].split('\n'):
|
|
||||||
# dst = os.path.join(fetch_dst_directory, os.path.basename(src))
|
|
||||||
# fetch_url(src, dst)
|
|
||||||
|
|
||||||
modules.append(Module(path=path, name=name))
|
print('')
|
||||||
print_progress_bar(
|
|
||||||
text='- assembling modules:',
|
|
||||||
done=(i + 1),
|
|
||||||
total=len(sources),
|
|
||||||
width=30
|
|
||||||
)
|
|
||||||
# FIXME
|
|
||||||
# if config.has_option(section, 'fetch'):
|
|
||||||
# # when we fetch directly from autocmake.yml
|
|
||||||
# # we download into downloaded/
|
|
||||||
# for src in config.get(section, 'fetch').split('\n'):
|
|
||||||
# dst = os.path.join(download_directory, os.path.basename(src))
|
|
||||||
# fetch_url(src, dst)
|
|
||||||
print('')
|
|
||||||
|
|
||||||
if warnings != []:
|
return modules, cleaned_config
|
||||||
print('- {0}'.format('\n- '.join(warnings)))
|
|
||||||
|
|
||||||
return modules
|
|
||||||
|
|
||||||
|
|
||||||
def process_yaml(argv):
|
def process_yaml(argv):
|
||||||
from autocmake.parse_yaml import parse_yaml
|
from autocmake.parse_yaml import parse_yaml
|
||||||
from autocmake.generate import gen_cmakelists, gen_setup
|
from autocmake.generate import gen_cmakelists, gen_setup
|
||||||
|
from autocmake.extract import extract_list
|
||||||
|
|
||||||
project_root = argv[1]
|
project_root = argv[1]
|
||||||
if not os.path.isdir(project_root):
|
if not os.path.isdir(project_root):
|
||||||
@ -149,8 +138,25 @@ def process_yaml(argv):
|
|||||||
# get relative path from setup script to this directory
|
# get relative path from setup script to this directory
|
||||||
relative_path = os.path.relpath(os.path.abspath('.'), project_root)
|
relative_path = os.path.relpath(os.path.abspath('.'), project_root)
|
||||||
|
|
||||||
|
download_directory = 'downloaded'
|
||||||
|
if not os.path.exists(download_directory):
|
||||||
|
os.makedirs(download_directory)
|
||||||
|
|
||||||
# fetch modules from the web or from relative paths
|
# fetch modules from the web or from relative paths
|
||||||
modules = fetch_modules(config, relative_path)
|
modules, cleaned_config = fetch_modules(config, relative_path, download_directory)
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
# for k, v in cleaned_config.items():
|
||||||
|
# print(k, v)
|
||||||
|
|
||||||
|
# fetch files which are not parsed
|
||||||
|
for src in extract_list(config, 'fetch'):
|
||||||
|
dst = os.path.join(download_directory, os.path.basename(src))
|
||||||
|
fetch_url(src, dst)
|
||||||
|
|
||||||
|
# print warnings
|
||||||
|
for warning in extract_list(config, 'warning'):
|
||||||
|
print('- WARNING: {0}'.format(warning))
|
||||||
|
|
||||||
# create CMakeLists.txt
|
# create CMakeLists.txt
|
||||||
print('- generating CMakeLists.txt')
|
print('- generating CMakeLists.txt')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user