aboutsummaryrefslogtreecommitdiffstats
path: root/wscript
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-07-07 18:59:06 -0400
committerDavid Robillard <d@drobilla.net>2022-07-17 18:13:53 -0400
commitd4a970f6962dda28133290194832b726b566ddab (patch)
treecfe9747042d55388705371a8ce95505ffb702470 /wscript
parent7f3a2651a3635232d94f7bf9ce23d6b575735732 (diff)
downloadlv2-d4a970f6962dda28133290194832b726b566ddab.tar.xz
Switch to meson build system
Diffstat (limited to 'wscript')
-rw-r--r--wscript850
1 files changed, 0 insertions, 850 deletions
diff --git a/wscript b/wscript
deleted file mode 100644
index 43206ec..0000000
--- a/wscript
+++ /dev/null
@@ -1,850 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import re
-import sys
-
-from waflib import Build, Context, Logs, Options, Scripting, Utils
-from waflib.extras import autowaf as autowaf
-
-# Mandatory waf variables
-APPNAME = 'lv2' # Package name for waf dist
-VERSION = '1.18.5' # Package version for waf dist
-top = '.' # Source directory
-out = 'build' # Build directory
-
-# Release variables
-title = 'LV2'
-uri = 'http://lv2plug.in/ns/lv2'
-dist_pattern = 'http://lv2plug.in/spec/lv2-%d.%d.%d.tar.bz2'
-post_tags = []
-
-# Links for documentation
-list_email = 'devel@lists.lv2plug.in'
-list_page = 'http://lists.lv2plug.in/listinfo.cgi/devel-lv2plug.in'
-
-# Map of specification base name to old URI-style include path
-spec_map = {
- 'atom': 'lv2/lv2plug.in/ns/ext/atom',
- 'buf-size': 'lv2/lv2plug.in/ns/ext/buf-size',
- 'core': 'lv2/lv2plug.in/ns/lv2core',
- 'data-access': 'lv2/lv2plug.in/ns/ext/data-access',
- 'dynmanifest': 'lv2/lv2plug.in/ns/ext/dynmanifest',
- 'event': 'lv2/lv2plug.in/ns/ext/event',
- 'instance-access': 'lv2/lv2plug.in/ns/ext/instance-access',
- 'log': 'lv2/lv2plug.in/ns/ext/log',
- 'midi': 'lv2/lv2plug.in/ns/ext/midi',
- 'morph': 'lv2/lv2plug.in/ns/ext/morph',
- 'options': 'lv2/lv2plug.in/ns/ext/options',
- 'parameters': 'lv2/lv2plug.in/ns/ext/parameters',
- 'patch': 'lv2/lv2plug.in/ns/ext/patch',
- 'port-groups': 'lv2/lv2plug.in/ns/ext/port-groups',
- 'port-props': 'lv2/lv2plug.in/ns/ext/port-props',
- 'presets': 'lv2/lv2plug.in/ns/ext/presets',
- 'resize-port': 'lv2/lv2plug.in/ns/ext/resize-port',
- 'state': 'lv2/lv2plug.in/ns/ext/state',
- 'time': 'lv2/lv2plug.in/ns/ext/time',
- 'ui': 'lv2/lv2plug.in/ns/extensions/ui',
- 'units': 'lv2/lv2plug.in/ns/extensions/units',
- 'uri-map': 'lv2/lv2plug.in/ns/ext/uri-map',
- 'urid': 'lv2/lv2plug.in/ns/ext/urid',
- 'worker': 'lv2/lv2plug.in/ns/ext/worker'}
-
-
-def options(ctx):
- ctx.load('compiler_c')
- ctx.load('compiler_cxx')
- ctx.load('lv2')
- ctx.add_flags(
- ctx.configuration_options(),
- {'no-coverage': 'Do not use gcov for code coverage',
- 'online-docs': 'Build documentation for web hosting',
- 'no-check-links': 'Do not check documentation for broken links',
- 'no-plugins': 'Do not build example plugins',
- 'copy-headers': 'Copy headers instead of linking to bundle'})
-
-
-def configure(conf):
- try:
- conf.load('compiler_c', cache=True)
- except Exception:
- Options.options.build_tests = False
- Options.options.no_plugins = True
-
- try:
- conf.load('compiler_cxx', cache=True)
- except Exception:
- pass
-
- if Options.options.online_docs:
- Options.options.docs = True
-
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- if Options.options.strict:
- # Check for programs used by lint target
- conf.find_program("flake8", var="FLAKE8", mandatory=False)
- conf.find_program("clang-tidy", var="CLANG_TIDY", mandatory=False)
- conf.find_program("iwyu_tool", var="IWYU_TOOL", mandatory=False)
-
- if Options.options.ultra_strict:
- autowaf.add_compiler_flags(conf.env, 'c', {
- 'gcc': [
- '-Wno-bad-function-cast',
- ],
- 'clang': [
- '-Wno-bad-function-cast',
- ]
- })
-
- autowaf.add_compiler_flags(conf.env, '*', {
- 'clang': [
- '-Wno-cast-align',
- '-Wno-cast-qual',
- '-Wno-documentation-unknown-command',
- '-Wno-double-promotion',
- '-Wno-float-conversion',
- '-Wno-float-equal',
- '-Wno-implicit-float-conversion',
- '-Wno-padded',
- '-Wno-poison-system-directories',
- '-Wno-reserved-id-macro',
- '-Wno-shorten-64-to-32',
- '-Wno-sign-conversion',
- '-Wno-switch-enum',
- '-Wno-unused-parameter',
- ],
- 'gcc': [
- '-Wno-cast-align',
- '-Wno-cast-qual',
- '-Wno-conversion',
- '-Wno-double-promotion',
- '-Wno-float-equal',
- '-Wno-inline',
- '-Wno-padded',
- '-Wno-suggest-attribute=const',
- '-Wno-suggest-attribute=malloc',
- '-Wno-suggest-attribute=pure',
- '-Wno-switch-enum',
- '-Wno-unused-parameter',
- ],
- 'msvc': [
- '/wd4061', # enumerator in switch is not explicitly handled
- '/wd4100', # unreferenced formal parameter
- '/wd4244', # conversion with possible loss of data
- '/wd4267', # conversion from size_t to a smaller type
- '/wd4310', # cast truncates constant value
- '/wd4365', # signed/unsigned mismatch
- '/wd4464', # relative include path contains ".."
- '/wd4514', # unreferenced inline function has been removed
- '/wd4706', # assignment within conditional expression
- '/wd4710', # function not inlined
- '/wd4711', # function selected for automatic inline expansion
- '/wd4820', # padding added after construct
- '/wd5045', # will insert Spectre mitigation for memory load
- ]
- })
-
- autowaf.add_compiler_flags(conf.env, 'cxx', {
- 'gcc': [
- '-Wno-useless-cast',
- '-Wno-zero-as-null-pointer-constant',
- ],
- 'clang': [
- '-Wno-old-style-cast',
- '-Wno-zero-as-null-pointer-constant',
- ]
- })
-
- if 'mingw' in conf.env.CC[0]:
- autowaf.add_compiler_flags(conf.env, '*', {
- 'gcc': [
- '-Wno-format',
- '-Wno-suggest-attribute=format',
- ],
- })
-
- autowaf.set_c_lang(conf, 'c99')
-
- if conf.env.DEST_OS == 'win32' or not hasattr(os.path, 'relpath'):
- Logs.warn('System does not support linking headers, copying')
- Options.options.copy_headers = True
-
- conf.env.BUILD_TESTS = Options.options.build_tests
- conf.env.BUILD_PLUGINS = not Options.options.no_plugins
- conf.env.COPY_HEADERS = Options.options.copy_headers
- conf.env.ONLINE_DOCS = Options.options.online_docs
-
- if conf.env.DOCS or conf.env.ONLINE_DOCS:
- try:
- conf.find_program('asciidoc')
- conf.env.BUILD_BOOK = True
- except Exception:
- Logs.warn('Asciidoc not found, book will not be built')
-
- if not Options.options.no_check_links:
- if not conf.find_program('linkchecker',
- var='LINKCHECKER', mandatory=False):
- Logs.warn('Documentation will not be checked for broken links')
-
- # Check for gcov library (for test coverage)
- if (conf.env.BUILD_TESTS and
- not Options.options.no_coverage and
- not conf.is_defined('HAVE_GCOV')):
- conf.check_cc(lib='gcov', define_name='HAVE_GCOV', mandatory=False)
-
- if conf.env.BUILD_TESTS:
- conf.find_program('serdi', mandatory=False)
- conf.find_program('sord_validate', mandatory=False)
- conf.find_program('codespell', mandatory=False)
-
- autowaf.set_lib_env(conf, 'lv2', VERSION, has_objects=False)
- autowaf.set_local_lib(conf, 'lv2', has_objects=False)
-
- conf.run_env.append_unique('LV2_PATH',
- [os.path.join(conf.path.abspath(), 'lv2')])
-
- if conf.env.BUILD_PLUGINS:
- for i in ['eg-amp.lv2',
- 'eg-fifths.lv2',
- 'eg-metro.lv2',
- 'eg-midigate.lv2',
- 'eg-params.lv2',
- 'eg-sampler.lv2',
- 'eg-scope.lv2']:
- try:
- path = os.path.join('plugins', i)
- conf.recurse(path)
- conf.env.LV2_BUILD += [path]
- conf.run_env.append_unique(
- 'LV2_PATH', [conf.build_path('plugins/%s/lv2' % i)])
- except Exception as e:
- Logs.warn('Configuration of %s failed (%s)' % (i, e))
-
- autowaf.display_summary(
- conf,
- {'Bundle directory': conf.env.LV2DIR,
- 'Copy (not link) headers': bool(conf.env.COPY_HEADERS),
- 'Version': VERSION})
-
-
-def chop_lv2_prefix(s):
- if s.startswith('lv2/lv2plug.in/'):
- return s[len('lv2/lv2plug.in/'):]
- return s
-
-
-def subst_file(template, output, dict):
- i = open(template, 'r')
- o = open(output, 'w')
- for line in i:
- for key in dict:
- line = line.replace(key, dict[key])
- o.write(line)
- i.close()
- o.close()
-
-
-def specdirs(path):
- return (path.ant_glob('lv2/*', dir=True) +
- path.ant_glob('plugins/*.lv2', dir=True))
-
-
-def ttl_files(path, specdir):
- def abspath(node):
- return node.abspath()
-
- return map(abspath,
- path.ant_glob(specdir.path_from(path) + '/*.ttl'))
-
-
-def load_ttl(files, exclude = []):
- import rdflib
- model = rdflib.ConjunctiveGraph()
- for f in files:
- if f not in exclude:
- model.parse(f, format='n3')
- return model
-
-
-# Task to build extension index
-def build_index(task):
- src_dir = task.inputs[0].parent.parent
- sys.path.append(str(src_dir.find_node('lv2specgen')))
- import rdflib
-
- doap = rdflib.Namespace('http://usefulinc.com/ns/doap#')
-
- model = load_ttl([str(src_dir.find_node('lv2/core/meta.ttl')),
- str(src_dir.find_node('lv2/core/people.ttl'))])
-
- # Get date for this version, and list of all LV2 distributions
- proj = rdflib.URIRef('http://lv2plug.in/ns/lv2')
- date = None
- dists = []
- for r in model.triples([proj, doap.release, None]):
- revision = model.value(r[2], doap.revision, None)
- created = model.value(r[2], doap.created, None)
- if str(revision) == VERSION:
- date = created
-
- dist = model.value(r[2], doap['file-release'], None)
- if dist and created:
- dists += [(created, dist)]
- else:
- print('warning: %s has no file release\n' % proj)
-
- rows = []
- for f in task.inputs:
- if not f.abspath().endswith('index.html.in'):
- rowfile = open(f.abspath(), 'r')
- rows += rowfile.readlines()
- rowfile.close()
-
- if date is None:
- import datetime
- import time
- now = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
- date = datetime.datetime.utcfromtimestamp(now).strftime('%F')
-
- subst_file(task.inputs[0].abspath(), task.outputs[0].abspath(),
- {'@ROWS@': ''.join(rows),
- '@LV2_VERSION@': VERSION,
- '@DATE@': date})
-
-
-def build_spec(bld, path):
- name = os.path.basename(path)
- bundle_dir = os.path.join(bld.env.LV2DIR, name + '.lv2')
- include_dir = os.path.join(bld.env.INCLUDEDIR, path)
- old_include_dir = os.path.join(bld.env.INCLUDEDIR, spec_map[name])
-
- # Build test program if applicable
- for test in bld.path.ant_glob(os.path.join(path, '*-test.c')):
- test_lib = []
- test_cflags = ['']
- test_linkflags = ['']
- if bld.is_defined('HAVE_GCOV'):
- test_lib += ['gcov']
- test_cflags += ['--coverage']
- test_linkflags += ['--coverage']
- if bld.env.DEST_OS not in ['darwin', 'win32']:
- test_lib += ['rt']
-
- # Unit test program
- bld(features = 'c cprogram',
- source = test,
- lib = test_lib,
- uselib = 'LV2',
- target = os.path.splitext(str(test.get_bld()))[0],
- install_path = None,
- cflags = test_cflags,
- linkflags = test_linkflags)
-
- # Install bundle
- bld.install_files(bundle_dir,
- bld.path.ant_glob(path + '/?*.*', excl='*.in'))
-
- # Install URI-like includes
- headers = bld.path.ant_glob(path + '/*.h')
- if headers:
- for d in [include_dir, old_include_dir]:
- if bld.env.COPY_HEADERS:
- bld.install_files(d, headers)
- else:
- bld.symlink_as(d,
- os.path.relpath(bundle_dir, os.path.dirname(d)))
-
-
-def build(bld):
- specs = (bld.path.ant_glob('lv2/*', dir=True))
-
- # Copy lv2.h to include directory for backwards compatibility
- old_lv2_h_path = os.path.join(bld.env.INCLUDEDIR, 'lv2.h')
- if bld.env.COPY_HEADERS:
- bld.install_files(os.path.dirname(old_lv2_h_path), 'lv2/core/lv2.h')
- else:
- bld.symlink_as(old_lv2_h_path, 'lv2/core/lv2.h')
-
- # LV2 pkgconfig file
- bld(features = 'subst',
- source = 'lv2.pc.in',
- target = 'lv2.pc',
- install_path = '${LIBDIR}/pkgconfig',
- PREFIX = bld.env.PREFIX,
- INCLUDEDIR = bld.env.INCLUDEDIR,
- VERSION = VERSION)
-
- # Validator
- bld(features = 'subst',
- source = 'util/lv2_validate.in',
- target = 'lv2_validate',
- chmod = Utils.O755,
- install_path = '${BINDIR}',
- LV2DIR = bld.env.LV2DIR)
-
- # Build extensions
- for spec in specs:
- build_spec(bld, spec.path_from(bld.path))
-
- # Build plugins
- for plugin in bld.env.LV2_BUILD:
- bld.recurse(plugin)
-
- # Install lv2specgen
- bld.install_files('${DATADIR}/lv2specgen/',
- ['doc/style.css',
- 'lv2specgen/template.html'])
- bld.install_files('${DATADIR}/lv2specgen/DTD/',
- bld.path.ant_glob('lv2specgen/DTD/*'))
- bld.install_files('${BINDIR}', 'lv2specgen/lv2specgen.py',
- chmod=Utils.O755)
-
- # Install schema bundle
- bld.install_files('${LV2DIR}/schemas.lv2/',
- bld.path.ant_glob('schemas.lv2/*.ttl'))
-
- if bld.env.ONLINE_DOCS:
- # Generate .htaccess files
- for d in ('ns', 'ns/ext', 'ns/extensions'):
- path = os.path.join(str(bld.path.get_bld()), d)
- bld(features = 'subst',
- source = 'doc/htaccess.in',
- target = os.path.join(path, '.htaccess'),
- install_path = None,
- BASE = '/' + d)
-
- if bld.env.DOCS or bld.env.ONLINE_DOCS:
- # Copy spec files to build dir
- for spec in specs:
- srcpath = spec.path_from(bld.path)
- basename = os.path.basename(srcpath)
- full_path = spec_map[basename]
- name = 'lv2core' if basename == 'core' else basename
- path = chop_lv2_prefix(full_path)
-
- bld(features = 'subst',
- is_copy = True,
- source = os.path.join(srcpath, name + '.ttl'),
- target = path + '.ttl')
-
- # Copy stylesheets to build directory
- for i in ['style.css', 'pygments.css']:
- bld(features = 'subst',
- is_copy = True,
- name = 'copy',
- source = 'doc/%s' % i,
- target = 'aux/%s' % i)
-
- # Build Doxygen documentation (and tags file)
- autowaf.build_dox(bld, 'LV2', VERSION, top, out, 'doc', False)
- bld.add_group()
-
- index_files = []
- for spec in specs:
- # Call lv2specgen to generate spec docs
- srcpath = spec.path_from(bld.path)
- basename = os.path.basename(srcpath)
- full_path = spec_map[basename]
- name = 'lv2core' if basename == 'core' else basename
- ttl_name = name + '.ttl'
- index_file = bld.path.get_bld().make_node('index_rows/' + name)
- index_files += [index_file]
- chopped_path = chop_lv2_prefix(full_path)
-
- assert chopped_path.startswith('ns/')
- root_path = os.path.relpath('/', os.path.dirname(chopped_path[2:]))
- html_path = '%s.html' % chopped_path
- out_dir = os.path.dirname(html_path)
- style_uri = os.path.relpath('aux/style.css', out_dir)
-
- cmd = (str(bld.path.find_node('lv2specgen/lv2specgen.py')) +
- ' --root-uri=http://lv2plug.in/ns/'
- ' --root-path=' + root_path +
- ' --list-email=' + list_email +
- ' --list-page=' + list_page +
- ' --style-uri=' + style_uri +
- ' --docdir=' + os.path.relpath('doc/html', out_dir) +
- ' --tags=%s' % bld.path.get_bld().make_node('doc/tags') +
- ' --index=' + str(index_file) +
- (' --online' if bld.env.ONLINE_DOCS else '') +
- ' ${SRC} ${TGT}')
-
- bld(rule = cmd,
- source = os.path.join(srcpath, ttl_name),
- target = [html_path, index_file],
- shell = False)
-
- # Install documentation
- bld.install_files(
- os.path.join('${DOCDIR}', 'lv2', os.path.dirname(html_path)),
- html_path)
-
- index_files.sort(key=lambda x: x.path_from(bld.path))
- bld.add_group()
-
- # Build extension index
- bld(rule = build_index,
- name = 'index',
- source = ['doc/index.html.in'] + index_files,
- target = 'ns/index.html')
-
- # Install main documentation files
- bld.install_files('${DOCDIR}/lv2/aux/', 'aux/style.css')
- bld.install_files('${DOCDIR}/lv2/ns/', 'ns/index.html')
-
- def check_links(ctx):
- import subprocess
- if ctx.env.LINKCHECKER:
- if subprocess.call([ctx.env.LINKCHECKER[0],
- '--no-status', out]):
- ctx.fatal('Documentation contains broken links')
-
- if bld.cmd == 'build':
- bld.add_post_fun(check_links)
-
- if bld.env.BUILD_TESTS:
- # Generate a compile test file that includes all headers
- def gen_build_test(task):
- with open(task.outputs[0].abspath(), 'w') as out:
- for i in task.inputs:
- out.write('#include "%s"\n' % i.bldpath())
- out.write('int main(void) { return 0; }\n')
-
- bld(rule = gen_build_test,
- source = bld.path.ant_glob('lv2/**/*.h'),
- target = 'build-test.c',
- install_path = None)
-
- bld(features = 'c cprogram',
- source = bld.path.get_bld().make_node('build-test.c'),
- target = 'build-test',
- includes = '.',
- uselib = 'LV2',
- install_path = None)
-
- if 'COMPILER_CXX' in bld.env:
- bld(rule = gen_build_test,
- source = bld.path.ant_glob('lv2/**/*.h'),
- target = 'build-test.cpp',
- install_path = None)
-
- bld(features = 'cxx cxxprogram',
- source = bld.path.get_bld().make_node('build-test.cpp'),
- target = 'build-test-cpp',
- includes = '.',
- uselib = 'LV2',
- install_path = None)
-
- if bld.env.BUILD_BOOK:
- # Build "Programming LV2 Plugins" book from plugin examples
- bld.recurse('plugins')
-
-
-class LintContext(Build.BuildContext):
- fun = cmd = 'lint'
-
-
-def lint(ctx):
- "checks code for style issues"
- import subprocess
- import glob
-
- st = 0
-
- if "FLAKE8" in ctx.env:
- Logs.info("Running flake8")
- st = subprocess.call([ctx.env.FLAKE8[0],
- "wscript",
- "--ignore",
- "E101,E129,W191,E221,W504,E251,E241,E741"])
- else:
- Logs.warn("Not running flake8")
-
- if "IWYU_TOOL" in ctx.env:
- Logs.info("Running include-what-you-use")
- cmd = [ctx.env.IWYU_TOOL[0], "-o", "clang", "-p", "build"]
- output = subprocess.check_output(cmd).decode('utf-8')
- if 'error: ' in output:
- sys.stdout.write(output)
- st += 1
- else:
- Logs.warn("Not running include-what-you-use")
-
- if "CLANG_TIDY" in ctx.env and "clang" in ctx.env.CC[0]:
- Logs.info("Running clang-tidy")
- sources = glob.glob('**/*.h', recursive=True)
- sources = list(map(os.path.abspath, sources))
- procs = []
- for source in sources:
- cmd = [ctx.env.CLANG_TIDY[0], "--quiet", "-p=.", source]
- procs += [subprocess.Popen(cmd, cwd="build")]
-
- for proc in procs:
- stdout, stderr = proc.communicate()
- st += proc.returncode
- else:
- Logs.warn("Not running clang-tidy")
-
- if st != 0:
- sys.exit(st)
-
-
-def test_vocabularies(check, specs, files):
- import rdflib
-
- foaf = rdflib.Namespace('http://xmlns.com/foaf/0.1/')
- lv2 = rdflib.Namespace('http://lv2plug.in/ns/lv2core#')
- owl = rdflib.Namespace('http://www.w3.org/2002/07/owl#')
- rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
- rdfs = rdflib.Namespace('http://www.w3.org/2000/01/rdf-schema#')
-
- # Check if this is a stable LV2 release to enable additional tests
- version_tuple = tuple(map(int, VERSION.split(".")))
- is_stable = version_tuple[1] % 2 == 0 and version_tuple[2] % 2 == 0
-
- # Check that extended documentation is not in main specification file
- for spec in specs:
- path = str(spec.abspath())
- name = os.path.basename(path)
- name = 'lv2core' if name == 'core' else name
- vocab = os.path.join(path, name + '.ttl')
-
- spec_model = rdflib.ConjunctiveGraph()
- spec_model.parse(vocab, format='n3')
-
- def has_statement(s, p, o):
- for t in spec_model.triples([s, p, o]):
- return True
-
- return False
-
- check(lambda: not has_statement(None, lv2.documentation, None),
- name = name + ".ttl does not contain lv2:documentation")
-
- # Check specification manifests
- for spec in specs:
- path = str(spec.abspath())
- manifest_path = os.path.join(path, 'manifest.ttl')
- manifest_model = rdflib.ConjunctiveGraph()
- manifest_model.parse(manifest_path, format='n3')
-
- uri = manifest_model.value(None, rdf.type, lv2.Specification)
- minor = manifest_model.value(uri, lv2.minorVersion, None)
- micro = manifest_model.value(uri, lv2.microVersion, None)
- check(lambda: uri is not None,
- name = manifest_path + " has a lv2:Specification")
- check(lambda: minor is not None,
- name = manifest_path + " has a lv2:minorVersion")
- check(lambda: micro is not None,
- name = manifest_path + " has a lv2:microVersion")
-
- if is_stable:
- check(lambda: int(minor) > 0,
- name = manifest_path + " has even non-zero minor version")
- check(lambda: int(micro) % 2 == 0,
- name = manifest_path + " has even micro version")
-
- # Load everything into one big model
- model = rdflib.ConjunctiveGraph()
- for f in files:
- model.parse(f, format='n3')
-
- # Check that all named and typed resources have labels and comments
- for r in sorted(model.triples([None, rdf.type, None])):
- subject = r[0]
- if (type(subject) == rdflib.term.BNode or
- foaf.Person in model.objects(subject, rdf.type)):
- continue
-
- def has_property(subject, prop):
- return model.value(subject, prop, None) is not None
-
- check(lambda: has_property(subject, rdfs.label),
- name = '%s has rdfs:label' % subject)
-
- if check(lambda: has_property(subject, rdfs.comment),
- name = '%s has rdfs:comment' % subject):
- comment = str(model.value(subject, rdfs.comment, None))
-
- check(lambda: comment.endswith('.'),
- name = "%s comment ends in '.'" % subject)
- check(lambda: comment.find('\n') == -1,
- name = "%s comment contains no newlines" % subject)
- check(lambda: comment == comment.strip(),
- name = "%s comment has stripped whitespace" % subject)
-
- # Check that lv2:documentation, if present, is proper Markdown
- documentation = model.value(subject, lv2.documentation, None)
- if documentation is not None:
- check(lambda: documentation.datatype == lv2.Markdown,
- name = "%s documentation is explicitly Markdown" % subject)
- check(lambda: str(documentation).startswith('\n\n'),
- name = "%s documentation starts with blank line" % subject)
- check(lambda: str(documentation).endswith('\n\n'),
- name = "%s documentation ends with blank line" % subject)
-
- # Check that all properties are either datatype or object properties
- for r in sorted(model.triples([None, rdf.type, rdf.Property])):
- subject = r[0]
- if str(subject) == 'http://lv2plug.in/ns/ext/patch#value':
- continue # patch:value is just a "promiscuous" rdf:Property
-
- types = list(model.objects(subject, rdf.type))
-
- check(lambda: ((owl.DatatypeProperty in types) or
- (owl.ObjectProperty in types) or
- (owl.AnnotationProperty in types)),
- name = "%s is a Datatype/Object/Annotation property" % subject)
-
-
-def test(tst):
- import tempfile
-
- with tst.group("Data") as check:
- specs = (tst.path.ant_glob('lv2/*', dir=True))
- schemas = list(map(str, tst.path.ant_glob("schemas.lv2/*.ttl")))
- spec_files = list(map(str, tst.path.ant_glob("lv2/**/*.ttl")))
- plugin_files = list(map(str, tst.path.ant_glob("plugins/**/*.ttl")))
- bld_files = list(map(str, tst.path.get_bld().ant_glob("**/*.ttl")))
-
- if "SERDI" in tst.env and sys.platform != 'win32':
- for f in spec_files:
- with tempfile.NamedTemporaryFile(mode="w") as tmp:
- base_dir = os.path.dirname(f)
- cmd = tst.env.SERDI + ["-o", "turtle", f, base_dir]
- check(cmd, stdout=tmp.name)
- check.file_equals(f, tmp.name)
-
- if "SORD_VALIDATE" in tst.env:
- all_files = schemas + spec_files + plugin_files + bld_files
- check(tst.env.SORD_VALIDATE + all_files)
-
- if "CODESPELL" in tst.env:
- spell_ignore_paths = [
- "doc/pygments.css",
- "schemas.lv2/doap.ttl",
- ]
-
- check(tst.env.CODESPELL + [
- "-d",
- "-q", "3",
- "-S", ','.join(tst.src_path(p) for p in spell_ignore_paths),
- tst.src_path("lv2specgen/*.*"),
- tst.src_path("doc"),
- tst.src_path("lv2"),
- tst.src_path("plugins"),
- tst.src_path("schemas.lv2"),
- tst.src_path("scripts"),
- ])
-
- try:
- test_vocabularies(check, specs, spec_files)
- except ImportError as e:
- Logs.warn('Not running vocabulary tests (%s)' % e)
-
- with tst.group('Unit') as check:
- pattern = tst.env.cprogram_PATTERN % '**/*-test'
- for test in tst.path.get_bld().ant_glob(pattern):
- check([str(test)])
-
-
-class Dist(Scripting.Dist):
- def execute(self):
- 'Execute but do not call archive() since dist() has already done so.'
- self.recurse([os.path.dirname(Context.g_module.root_path)])
-
- def get_tar_path(self, node):
- 'Resolve symbolic links to avoid broken links in tarball.'
- return os.path.realpath(node.abspath())
-
-
-class DistCheck(Dist, Scripting.DistCheck):
- def execute(self):
- Dist.execute(self)
- self.check()
-
- def archive(self):
- Dist.archive(self)
-
-
-def _get_news_entries(ctx):
- from waflib.extras import autoship
-
- # Get project-level news entries
- lv2_entries = autoship.read_ttl_news('lv2',
- ['lv2/core/meta.ttl',
- 'lv2/core/people.ttl'],
- dist_pattern = dist_pattern)
-
- release_pattern = r'http://lv2plug.in/spec/lv2-([0-9\.]*).tar.bz2'
- current_version = sorted(lv2_entries.keys(), reverse=True)[0]
-
- # Add items from every specification
- for specdir in specdirs(ctx.path):
- name = os.path.basename(specdir.abspath())
- files = list(ttl_files(ctx.path, specdir))
- if name == "core":
- files = [f for f in files if (not f.endswith('/meta.ttl') and
- not f.endswith('/people.ttl') and
- not f.endswith('/manifest.ttl'))]
-
- entries = autoship.read_ttl_news(name, files)
-
- def add_items(lv2_version, name, items):
- for item in items:
- lv2_entries[lv2_version]["items"] += ["%s: %s" % (name, item)]
-
- if entries:
- latest_revision = sorted(entries.keys(), reverse=True)[0]
- for revision, entry in entries.items():
- if "dist" in entry:
- match = re.match(release_pattern, entry["dist"])
- if match:
- # Append news items to corresponding LV2 version
- version = tuple(map(int, match.group(1).split('.')))
- add_items(version, name, entry["items"])
-
- elif revision == latest_revision:
- # Not-yet-released development version, append to current
- add_items(current_version, name, entry["items"])
-
- # Sort news items in each versions
- for revision, entry in lv2_entries.items():
- entry["items"].sort()
-
- return lv2_entries
-
-
-def posts(ctx):
- "generates news posts in Pelican Markdown format"
-
- from waflib.extras import autoship
-
- try:
- os.mkdir(os.path.join(out, 'posts'))
- except Exception:
- pass
-
- autoship.write_posts(_get_news_entries(ctx),
- os.path.join(out, 'posts'),
- {'Author': 'drobilla'})
-
-
-def news(ctx):
- """write an amalgamated NEWS file to the source directory"""
-
- from waflib.extras import autoship
-
- autoship.write_news(_get_news_entries(ctx), 'NEWS')
-
-
-def dist(ctx):
- news(ctx)
- ctx.archive()
-
-
-def distcheck(ctx):
- news(ctx)
- ctx.archive()