Skip to content

Commit

Permalink
A Changelog class
Browse files Browse the repository at this point in the history
  • Loading branch information
Ned Batchelder committed Dec 30, 2020
1 parent 4dbcb09 commit 12dd8d4
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 40 deletions.
46 changes: 7 additions & 39 deletions src/scriv/collect.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
"""Collecting fragments."""

import datetime
import logging
from pathlib import Path
from typing import Optional

import click
import click_log
import jinja2

from .format import get_format_tools
from .gitinfo import git_add, git_config_bool, git_edit, git_rm
from .scriv import Scriv
from .util import cut_at_line

logger = logging.getLogger()

Expand Down Expand Up @@ -47,46 +42,19 @@ def collect(
scriv = Scriv()
logger.info("Collecting from {}".format(scriv.config.fragment_directory))
frags = scriv.fragments_to_combine()
sections = scriv.combine_fragments(frags)

changelog = Path(scriv.config.output_file)
newline = ""
if changelog.exists():
with changelog.open("r") as f:
changelog_text = f.read()
if f.newlines: # .newlines may be None, str, or tuple
if isinstance(f.newlines, str):
newline = f.newlines
else:
newline = f.newlines[0]
text_before, text_after = cut_at_line(
changelog_text, scriv.config.insert_marker
)
else:
text_before = ""
text_after = ""
changelog = scriv.changelog()
changelog.read()

format_tools = get_format_tools(scriv.config.format, scriv.config)
title_data = {
"date": datetime.datetime.now(),
"version": version or scriv.config.version,
}
new_title = jinja2.Template(scriv.config.entry_title_template).render(
config=scriv.config, **title_data
)
if new_title.strip():
new_header = format_tools.format_header(new_title)
else:
new_header = ""
new_text = format_tools.format_sections(sections)
with changelog.open("w", newline=newline or None) as f:
f.write(text_before + new_header + new_text + text_after)
new_header = changelog.entry_header(version=version)
new_text = changelog.entry_text(scriv.combine_fragments(frags))
changelog.write(new_header, new_text)

if edit:
git_edit(changelog)
git_edit(changelog.path)

if add:
git_add(changelog)
git_add(changelog.path)

if not keep:
for frag in frags:
Expand Down
61 changes: 60 additions & 1 deletion src/scriv/scriv.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .config import Config
from .format import SectionDict, get_format_tools
from .gitinfo import current_branch_name, user_nick
from .util import order_dict
from .util import cut_at_line, order_dict


@attr.s
Expand All @@ -40,6 +40,58 @@ def read(self) -> None:
self.content = self.path.read_text()


@attr.s
class Changelog:
"""A changelog file."""

path = attr.ib(type=Path)
config = attr.ib(type=Config)
newline = attr.ib(type=str, default="")
text_before = attr.ib(type=str, default="")
text_after = attr.ib(type=str, default="")

def read(self) -> None:
"""Read the changelog if it exists."""
if self.path.exists():
with self.path.open("r") as f:
changelog_text = f.read()
if f.newlines: # .newlines may be None, str, or tuple
if isinstance(f.newlines, str):
self.newline = f.newlines
else:
self.newline = f.newlines[0]
self.text_before, self.text_after = cut_at_line(
changelog_text, self.config.insert_marker
)

def entry_header(self, date=None, version=None) -> str:
"""Format the header for a new entry."""
format_tools = get_format_tools(self.config.format, self.config)
title_data = {
"date": date or datetime.datetime.now(),
"version": version or self.config.version,
}
new_title = jinja2.Template(self.config.entry_title_template).render(
config=self.config, **title_data
)
if new_title.strip():
new_header = format_tools.format_header(new_title)
else:
new_header = ""
return new_header

def entry_text(self, sections: SectionDict) -> str:
"""Format the text of a new entry."""
format_tools = get_format_tools(self.config.format, self.config)
new_text = format_tools.format_sections(sections)
return new_text

def write(self, header: str, text: str) -> None:
"""Write the changelog, with a new entry."""
with self.path.open("w", newline=self.newline or None) as f:
f.write(self.text_before + header + text + self.text_after)


class Scriv:
"""Public API to the scriv application."""

Expand Down Expand Up @@ -86,6 +138,13 @@ def combine_fragments(self, fragments: Iterable[Fragment]) -> SectionDict:
sections = order_dict(sections, [None] + self.config.categories)
return sections

def changelog(self) -> Changelog:
"""Get the Changelog object."""
return Changelog(
path=Path(self.config.output_file),
config=self.config,
)


def new_fragment_path(config: Config) -> Path:
"""
Expand Down

0 comments on commit 12dd8d4

Please sign in to comment.