summaryrefslogtreecommitdiffstats
path: root/extras/autowaf.py
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-10-20 22:13:43 +0200
committerDavid Robillard <d@drobilla.net>2019-10-21 00:46:39 +0200
commita3600d61f63899e28f5208336b2c8371d8b331eb (patch)
tree28a58a1085d913a300bd7b796cfb9f1a454370d0 /extras/autowaf.py
parent66304cc4e1e10e03630e6a823f2bc9e0ec2c669a (diff)
downloadautowaf-a3600d61f63899e28f5208336b2c8371d8b331eb.tar.gz
autowaf-a3600d61f63899e28f5208336b2c8371d8b331eb.tar.bz2
autowaf-a3600d61f63899e28f5208336b2c8371d8b331eb.zip
Factor out release utilities
Diffstat (limited to 'extras/autowaf.py')
-rw-r--r--extras/autowaf.py267
1 files changed, 0 insertions, 267 deletions
diff --git a/extras/autowaf.py b/extras/autowaf.py
index fc1d488..2f2469b 100644
--- a/extras/autowaf.py
+++ b/extras/autowaf.py
@@ -1164,273 +1164,6 @@ def run_ldconfig(ctx):
except Exception:
pass
-def get_rdf_news(name,
- in_files,
- top_entries=None,
- extra_entries=None,
- dev_dist=None):
- import rdflib
- from time import strptime
-
- doap = rdflib.Namespace('http://usefulinc.com/ns/doap#')
- dcs = rdflib.Namespace('http://ontologi.es/doap-changeset#')
- rdfs = rdflib.Namespace('http://www.w3.org/2000/01/rdf-schema#')
- foaf = rdflib.Namespace('http://xmlns.com/foaf/0.1/')
- rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
- m = rdflib.ConjunctiveGraph()
-
- try:
- for i in in_files:
- m.parse(i, format='n3')
- except Exception:
- Logs.warn('Error parsing data, unable to generate NEWS')
- return
-
- proj = m.value(None, rdf.type, doap.Project)
- for f in m.triples([proj, rdfs.seeAlso, None]):
- if f[2].endswith('.ttl'):
- m.parse(f[2], format='n3')
-
- entries = {}
- for r in m.triples([proj, doap.release, None]):
- release = r[2]
- revision = m.value(release, doap.revision, None)
- date = m.value(release, doap.created, None)
- blamee = m.value(release, dcs.blame, None)
- changeset = m.value(release, dcs.changeset, None)
- dist = m.value(release, doap['file-release'], None)
-
- if not dist:
- Logs.warn('No file release for %s %s' % (proj, revision))
- dist = dev_dist
-
- if revision and date and blamee and changeset:
- entry = {}
- entry['name'] = str(name)
- entry['revision'] = str(revision)
- entry['date'] = strptime(str(date), '%Y-%m-%d')
- entry['status'] = 'stable' if dist != dev_dist else 'unstable'
- entry['dist'] = str(dist)
- entry['items'] = []
-
- for i in m.triples([changeset, dcs.item, None]):
- item = str(m.value(i[2], rdfs.label, None))
- entry['items'] += [item]
- if dist and top_entries is not None:
- if not str(dist) in top_entries:
- top_entries[str(dist)] = {'items': []}
- top_entries[str(dist)]['items'] += [
- '%s: %s' % (name, item)]
-
- if extra_entries and dist:
- for i in extra_entries[str(dist)]:
- entry['items'] += extra_entries[str(dist)]['items']
-
- entry['blamee_name'] = str(m.value(blamee, foaf.name, None))
- entry['blamee_mbox'] = str(m.value(blamee, foaf.mbox, None))
-
- entries[(str(date), str(revision))] = entry
- else:
- Logs.warn('Ignored incomplete %s release description' % name)
-
- return entries
-
-def write_news(entries, out_file):
- import textwrap
- from time import strftime
-
- if len(entries) == 0:
- return
-
- revisions = sorted(entries.keys(), reverse=True)
- news = open(out_file, 'w')
- for r in revisions:
- entry = entries[r]
- if r != revisions[0]:
- news.write('\n')
-
- news.write('%s (%s) %s;\n' % (entry['name'], entry['revision'], entry['status']))
- for item in entry['items']:
- wrapped = textwrap.wrap(item, width=74)
- news.write('\n * ' + '\n '.join(wrapped))
-
- news.write('\n\n --')
- news.write(' %s <%s>' % (entry['blamee_name'],
- entry['blamee_mbox'].replace('mailto:', '')))
-
- news.write(' %s\n' % (
- entry['date'].strftime('%a, %d %b %Y %H:%M:%S %z')))
-
- news.close()
-
-def get_items_markdown(items, indent=""):
- return ''.join([indent + '* %s\n' % item for item in items])
-
-def write_posts(entries, meta, out_dir, status='stable'):
- "Write news posts in Pelican Markdown format"
- import datetime
- try:
- os.mkdir(out_dir)
- except Exception:
- pass
-
- for r, entry in entries.items():
- revision = entry['revision']
- if entry['status'] != status:
- continue
-
- date = entry['date'].astimezone(datetime.timezone.utc)
- date_str = date.strftime('%Y-%m-%d')
- datetime_str = date.strftime('%Y-%m-%d %H:%M')
-
- path = os.path.join(out_dir, '%s-%s-%s.md' % (
- date_str, entry['name'], revision.replace('.', '-')))
- post = open(path, 'w')
- title = entry['title'] if 'title' in entry else entry['name']
- post.write('Title: %s %s\n' % (title, revision))
- post.write('Date: %s\n' % datetime_str)
- post.write('Slug: %s-%s\n' % (entry['name'], revision.replace('.', '-')))
- for k in meta:
- post.write('%s: %s\n' % (k, meta[k]))
- post.write('\n')
-
- url = entry['dist']
- if entry['status'] == status:
- post.write('[%s %s](%s) has been released.' % (
- (entry['name'], revision, url)))
-
- if 'description' in entry:
- post.write(' ' + entry['description'])
-
- post.write('\n')
- if (len(entry['items']) > 0 and
- not (len(entry['items']) == 1 and
- entry['items'][0] == 'Initial release')):
- post.write('\nChanges:\n\n')
- post.write(get_items_markdown(entry['items'], indent=" "))
-
- post.close()
-
-def get_blurb(in_file):
- "Get the first paragraph of a Markdown formatted file, skipping the title"
- f = open(in_file, 'r')
- f.readline() # Title
- f.readline() # Title underline
- f.readline() # Blank
- out = ''
- line = f.readline()
- while len(line) > 0 and line != '\n':
- out += line.replace('\n', ' ')
- line = f.readline()
- return out.strip()
-
-def get_news(in_file, entry_props={}):
- """Get NEWS entries in the format expected by write_posts().
-
- Properties that should be set on every entry can be passed in
- `entry_props`. If `entry_props` has a 'dist_pattern' value, it is used to
- set the 'dist' entry of entries by substituting the version number.
- """
-
- import re
- import email.utils
-
- f = open(in_file, 'r')
- entries = {}
- while True:
- # Read header line
- head = f.readline()
- matches = re.compile(r'([^ ]*) \((.*)\) ([a-zA-z]*);').match(head)
- if matches is None:
- break
-
- entry = {}
- entry['name'] = matches.group(1)
- entry['revision'] = matches.group(2)
- entry['status'] = matches.group(3)
- entry['items'] = []
- if 'dist_pattern' in entry_props:
- entry['dist'] = entry_props['dist_pattern'] % entry['revision']
-
- # Read blank line after header
- if f.readline() != '\n':
- raise SyntaxError('expected blank line after NEWS header')
-
- def add_item(item):
- if len(item) > 0:
- entry['items'] += [item.replace('\n', ' ').strip()]
-
- # Read entries for this revision
- item = ''
- line = ''
- while line != '\n':
- line = f.readline()
- if line.startswith(' * '):
- add_item(item)
- item = line[3:].lstrip()
- else:
- item += line.lstrip()
- add_item(item)
-
- # Read footer line
- foot = f.readline()
- matches = re.compile(' -- (.*) <(.*)> (.*)').match(foot)
- entry['date'] = email.utils.parsedate_to_datetime(matches.group(3))
- entry['blamee_name'] = matches.group(1)
- entry['blamee_mbox'] = matches.group(2)
- entry.update(entry_props)
-
- key = tuple(map(int, entry['revision'].split('.')))
- entries[key] = entry
-
- # Skip trailing blank line before next entry
- f.readline()
-
- f.close()
-
- return entries
-
-def news_to_posts(news_file, entry_props, post_meta, default_post_dir):
- post_dir = os.getenv('POST_DIR')
- if not post_dir:
- post_dir = default_post_dir
- sys.stderr.write('POST_DIR not set in environment, writing to %s\n' % post_dir)
- else:
- sys.stderr.write('writing posts to %s\n' % post_dir)
-
- entries = get_news(news_file, entry_props)
- write_posts(entries, post_meta, post_dir)
-
def run_script(cmds):
for cmd in cmds:
subprocess.check_call(cmd, shell=True)
-
-def release(name, version, dist_name=None):
- if dist_name is None:
- dist_name = name.lower()
-
- dist = '%s-%s.tar.bz2' % (dist_name or name.lower(), version)
- try:
- os.remove(dist)
- os.remove(dist + '.sig')
- except Exception:
- pass
-
- status = subprocess.check_output('git status --porcelain', shell=True)
- if status:
- Logs.error('error: git working copy is dirty\n' + status)
- raise Exception('git working copy is dirty')
-
- head = subprocess.check_output('git show -s --oneline', shell=True)
- head_summary = head[8:].strip().lower()
- expected_summary = '%s %s' % (name.lower(), version)
- if head_summary != expected_summary:
- raise Exception('latest commit "%s" does not match "%s"' % (
- head_summary, expected_summary))
-
- run_script(['./waf configure --docs',
- './waf',
- './waf distcheck',
- './waf posts',
- 'gpg -b %s' % dist,
- 'git tag -s v%s -m "%s %s"' % (version, name, version)])