1import json 2import os 3from datetime import date 4 5from changelog.model import ReleaseChanges, ChangelogEntry, Version 6 7 8def version_cmp(a,b): 9 aa = [a.major, a.minor, a.patch, a.prerelease_version_number()] 10 bb = [b.major, b.minor, b.patch, b.prerelease_version_number()] 11 return cmp(bb,aa) 12 13def load_all_released_changes(d): 14 if not os.path.isdir(d): 15 return [] 16 return [load_release_changes(os.path.join(d, fn)) for fn in os.listdir(d) if fn.endswith('.json')] 17 18def load_release_changes(fn): 19 with open(fn) as f: 20 return parse_release_changes(json.loads(f.read())) 21 22def load_unreleased_changes(d): 23 if not os.path.exists(d): 24 return None 25 return ReleaseChanges(None, date.today().isoformat(), load_unreleased_entries(d)) 26 27def load_unreleased_entries(d): 28 entries = [] 29 for f in [f for f in os.listdir(d) if f.endswith('.json')]: 30 with open(os.path.join(d,f)) as e: 31 entries.append(parse_changelog_entry(json.loads(e.read()))) 32 return entries 33 34def parse_release_changes(changes_json): 35 version = parse_version_string(changes_json['version']) 36 date = changes_json['date'] 37 entries = [parse_changelog_entry(e) for e in changes_json['entries']] 38 return ReleaseChanges(version, date, entries) 39 40def parse_changelog_entry(entry_json): 41 return ChangelogEntry(entry_json['type'], entry_json['category'], entry_json['description'], 42 entry_json.get('contributor')) 43 44def parse_version_string(s): 45 version_parts = [s for s in s.split('.')] 46 prerelease = "" 47 hyphen_index = version_parts[2].find('-') 48 if hyphen_index != -1: 49 p = version_parts[2] 50 version_parts[2] = p[0:hyphen_index] 51 prerelease = p[hyphen_index + 1:] 52 return Version(int(version_parts[0]), int(version_parts[1]), int(version_parts[2]), prerelease) 53 54class ReleaseChangesEncoder(json.JSONEncoder): 55 def default(self, o): 56 if type(o) is Version: 57 # store as a "MAJOR.MINOR.PATCH" string so it's a little easier to 58 # read the raw JSON 59 return o.__str__() 60 return o.__dict__ 61 62def marshall_release_changes(changes): 63 return json.dumps(changes, indent=4, separators=(',', ': '), cls=ReleaseChangesEncoder) 64