2021-04-17 21:35:44 +00:00
|
|
|
# yaclog-ksp: yet another changelog tool
|
|
|
|
# Copyright (c) 2021. Andrew Cassidy
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as
|
|
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
|
|
# License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
2021-04-17 21:37:28 +00:00
|
|
|
import pathlib
|
|
|
|
import re
|
2024-08-27 04:50:00 +00:00
|
|
|
from sys import stdout
|
|
|
|
|
2021-04-17 04:08:54 +00:00
|
|
|
import click
|
|
|
|
import yaclog
|
2021-04-17 21:37:28 +00:00
|
|
|
|
2021-04-17 04:08:54 +00:00
|
|
|
from yaclog_ksp.cfgnode import ConfigNode
|
|
|
|
|
|
|
|
|
|
|
|
@click.command()
|
2021-05-07 22:48:07 +00:00
|
|
|
@click.option('--path', envvar='YACLOG_PATH', default='CHANGELOG.md', show_default=True,
|
|
|
|
type=click.Path(dir_okay=False, writable=True, readable=True),
|
|
|
|
help='Location of the changelog file.')
|
2021-04-17 04:08:54 +00:00
|
|
|
@click.option('-o', '--output', 'outpath',
|
|
|
|
default=None,
|
|
|
|
type=click.Path(writable=True, dir_okay=False),
|
|
|
|
help="Output file to write to. Uses 'GameData/{name}/Versioning/{name}ChangeLog.cfg' by default.")
|
|
|
|
@click.option('-n', '--name', help="The name of the mod. Derived from the current directory by default.")
|
|
|
|
@click.version_option()
|
2021-05-07 22:48:07 +00:00
|
|
|
def main(path, outpath, name):
|
2021-04-17 04:08:54 +00:00
|
|
|
""" Converts markdown changelogs to KSP changelog configs."""
|
|
|
|
if not name:
|
|
|
|
# try to guess name from current directory
|
|
|
|
pathname = pathlib.Path.cwd().name.removeprefix('KSP-')
|
|
|
|
modslug = str.join('', [s.title() for s in re.split(r'[ _-]+', pathname)])
|
|
|
|
segments = re.findall(r'[A-Z](?:[a-z]+|[A-Z]*(?=[A-Z]|$))', modslug)
|
2024-08-26 06:03:03 +00:00
|
|
|
name = ' '.join(segments)
|
2021-04-17 04:08:54 +00:00
|
|
|
else:
|
|
|
|
modslug = str.join('', [s.title() for s in re.split(r'[ _-]+', name)])
|
|
|
|
|
|
|
|
if not outpath:
|
|
|
|
# default is in GameData/{name}/Versioning/{name}ChangeLog.cfg
|
|
|
|
outpath = pathlib.Path('GameData', modslug, 'Versioning', modslug + 'ChangeLog.cfg')
|
|
|
|
|
2021-05-07 22:48:07 +00:00
|
|
|
log = yaclog.read(path)
|
2021-04-17 04:08:54 +00:00
|
|
|
node = ConfigNode()
|
|
|
|
|
|
|
|
# find metadata table rows
|
2021-05-07 06:17:42 +00:00
|
|
|
for key, value in re.findall(r'^\|(?P<key>[^\n-]*?)\|(?P<value>[^\n-]*?)\|$', log.preamble, flags=re.MULTILINE):
|
2021-04-17 04:08:54 +00:00
|
|
|
key = key.strip()
|
|
|
|
value = value.strip()
|
|
|
|
if key.strip(':-'):
|
|
|
|
node.add_value(key, value)
|
|
|
|
|
|
|
|
# if modname not in metadata, then add it here
|
|
|
|
if not node.has_value('modName'):
|
|
|
|
node.add_value('modName', name)
|
|
|
|
|
|
|
|
# iterate through all versions
|
|
|
|
for version in log.versions:
|
|
|
|
v_node = node.add_new_node('VERSION')
|
|
|
|
v_node.add_value('version', version.name)
|
|
|
|
|
|
|
|
# add date
|
|
|
|
if version.date:
|
|
|
|
v_node.add_value('versionDate', str(version.date))
|
|
|
|
|
|
|
|
# check for KSP version tag and add it
|
|
|
|
for tag in version.tags:
|
|
|
|
if match := re.match(r'KSP (?P<versionKSP>.*)', tag):
|
|
|
|
v_node.add_value('versionKSP', match['versionKSP'])
|
|
|
|
break
|
|
|
|
|
|
|
|
# add entries
|
|
|
|
for section, entries in version.sections.items():
|
|
|
|
for entry in entries:
|
|
|
|
|
|
|
|
bullets = re.findall(r'^[\t ]*[-+*] (.*?)$', entry, flags=re.MULTILINE)
|
|
|
|
|
|
|
|
if len(bullets) < 1:
|
|
|
|
# not a bullet point, but a paragraph. all one string
|
|
|
|
change = entry.replace('\n', ' ')
|
|
|
|
subchanges = []
|
|
|
|
else:
|
|
|
|
# bullet point, may have sub points
|
|
|
|
change = bullets[0]
|
|
|
|
subchanges = bullets[1:]
|
|
|
|
|
2021-04-17 05:24:44 +00:00
|
|
|
if section or len(subchanges) > 0:
|
|
|
|
e_node = v_node.add_new_node('CHANGE')
|
|
|
|
|
|
|
|
if section:
|
|
|
|
# KerbalChangelog only actually cares about the first character,
|
|
|
|
# so dont bother correcting "Fixed"->"Fix", etc
|
|
|
|
e_node.add_value('type', section.title())
|
|
|
|
|
|
|
|
e_node.add_value('change', change)
|
|
|
|
for sc in subchanges:
|
|
|
|
e_node.add_value('subchange', sc)
|
|
|
|
|
|
|
|
else:
|
|
|
|
v_node.add_value('change', change)
|
2021-04-17 04:08:54 +00:00
|
|
|
|
|
|
|
with open(outpath, 'w') as fp:
|
2021-04-17 21:49:20 +00:00
|
|
|
fp.write('// Changelog file generated by yaclog-ksp (https://github.com/drewcassidy/yaclog-ksp)\n')
|
2021-04-17 04:08:54 +00:00
|
|
|
fp.write('KERBALCHANGELOG\n')
|
|
|
|
fp.write(str(node))
|
|
|
|
|
2024-08-27 04:50:00 +00:00
|
|
|
if stdout.isatty():
|
|
|
|
print(f'wrote output to {outpath}')
|
|
|
|
else:
|
|
|
|
print(outpath)
|
2021-04-17 04:08:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|