Package: blurb
Overviewblurbis a tool designed to rid CPython core development
of the scourge ofMisc/NEWSconflicts.The core concept: splitMisc/NEWSinto many
separate files that, when concatenated back together
in sorted order, reconstitute the originalMisc/NEWSfile.
After that,Misc/NEWScould be deleted from the CPython
repo and thereafter rendered on demand (e.g. when building
a release).  When checking in a change to CPython, the checkin
process will write out a new file that sorts into the correct place,
using a filename unlikely to have a merge conflict.blurbis a single command with a number of subcommands.
It’s designed  to be run inside a valid CPython (git) repo,
and automatically uses the correct file paths.You can installblurbfrom PyPI usingpip.  Alternatively,
simply addblurbto a directory on your path.blurb’s only dependency is Python 3.7+.Files used by blurbblurbuses a new directory tree calledMisc/NEWS.d.
Everything it does is in there, except for possibly
modifyingMisc/NEWS.UnderMisc/NEWS.dyou’ll find the following:A single file for all news entries per previous revision,
named for the exact version number, with the extension.rst.
Example:Misc/NEWS.d/3.6.0b2.rst.Thenextdirectory, which contains subdirectories representing
the variousMisc/NEWScategories.  Inside these subdirectories
are more.rstfiles with long, uninteresting, computer-generated
names.  Example:Misc/NEWS.d/next/Library/2017-05-04-12-24-06.gh-issue-25458.Yl4gI2.rstblurb subcommandsLike many modern utilities,blurbhas only one executable
(calledblurb), but provides a diverse set of functionality
through subcommands.  The subcommand is the first argument specified
on the command-line.If you’re a CPython core developer, you probably don’t need to use
anything exceptblurb add–and you don’t even need to specify
theaddpart.
(If no subcommand is specified,blurbassumes you meantblurb add.)
The other commands are only expected to be useful for CPython release
managers.blurb helpblurbis self-documenting through theblurb helpsubcommand.
Run without any further arguments, it prints a list of all subcommands,
with a one-line summary of the functionality of each.  Run with a
third argument, it prints help on that subcommand (e.g.blurb help release).blurb addblurb addadds a new Misc/NEWS entry for you.
It opens a text editor on a template; you edit the
file, save, and exit.blurbthen stores the file
in the correct place, and stages it ingitfor you.The template for theblurb addmessage looks like this:#
# Please enter the relevant GitHub issue number here:
#
.. gh-issue:

#
# Uncomment one of these "section:" lines to specify which section
# this entry should go in in Misc/NEWS.
#
#.. section: Security
#.. section: Core and Builtins
#.. section: Library
#.. section: Documentation
#.. section: Tests
#.. section: Build
#.. section: Windows
#.. section: macOS
#.. section: IDLE
#.. section: Tools/Demos
#.. section: C API

# Write your Misc/NEWS entry below.  It should be a simple ReST paragraph.
# Don't start with "- Issue #<n>: " or "- gh-issue<n>: " or that sort of stuff.
###########################################################################Here’s how you interact with the file:Add the GitHub issue number for this checkin to the
end of the..gh-issue:line.Uncomment the line with the relevantMisc/NEWSsection for this entry.
For example, if this should go in theLibrarysection, uncomment
the line reading#.. section: Library.  To uncomment, just delete
the#at the front of the line.Finally, go to the end of the file, and enter your NEWS entry.
This should be a single paragraph of English text using
simple ReST markup.Whenblurb addgets a valid entry, it writes it to a file
with the following format:Misc/NEWS.d/next/<section>/<datetime>.gh-issue-<issue_number>.<nonce>.rstFor example, a file added byblurb addmight look like this:Misc/NEWS.d/next/Library/2017-05-04-12-24-06.gh-issue-25458.Yl4gI2.rst<section>is the section provided in the checkin message.<datetime>is the current UTC time, formatted asYYYY-MM-DD-hh-mm-ss.<nonce>is a hopefully-unique string of characters meant to
prevent filename collisions.blurbcreates this by computing
the MD5 hash of the text, converting it to base64 (using the
“urlsafe” alphabet), and taking the first 6 characters of that.This filename ensures several things:All entries inMisc/NEWSwill be sorted by time.It is unthinkably unlikely that there’ll be a conflict
between the filenames generated for two developers checking in,
even if they check in at the exact same second.Finally,blurb addstages the file in git for you.blurb mergeblurb mergerecombines all the files in theMisc/NEWS.dtree back into a singleNEWSfile.blurb mergeaccepts only a single command-line argument:
the file to write to.  By default it writes toMisc/NEWS(relative to the root of your CPython checkout).Splitting and recombining the existingMisc/NEWSfile
doesn’t recreate the previousMisc/NEWSexactly.  This
is becauseMisc/NEWSnever used a consistent ordering
for the “sections” inside each release, whereasblurb mergehas a hard-coded preferred ordering for the sections.  Also,blurbaggressively reflows paragraphs to < 78 columns,
wheras the original hand-edited file occasionally had lines
> 80 columns.  Finally,blurbstrictly usesgh-issue-<n>:to
specify issue numbers at the beginnings of entries, wheras
the legacy approach toMisc/NEWSrequired usingIssue #<n>:.blurb releaseblurb releaseis used by the release manager as part of
the CPython release process.  It takes exactly one argument,
the name of the version being released.Here’s what it does under the hood:Combines all recently-added NEWS entries from
theMisc/NEWS.d/nextdirectory intoMisc/NEWS.d/<version>.rst.Runsblurb mergeto produce an updatedMisc/NEWSfile.One hidden feature: if the version specified is.,blurb releaseuses the name of the directory CPython is checked out to.
(When making a release I generally name the directory after the
version I’m releasing, and using this shortcut saves me some typing.)blurb splitblurb splitonly needs to be run once per-branch, ever.
It reads inMisc/NEWSand splits it into individual.rstfiles.
The text files are stored as follows:Misc/NEWS.d/<version>.rst<version>is the version number of Python where the
change was committed.  Pre-release versions are denoted
with an abbreviation:afor alphas,bfor betas,
andrcfor release candidates.The individual<version>.rstfiles actually (usually)
contain multiple entries.  Each entry is delimited by a
single line containing..by itself.The assumption is, at the point we convert over toblurb,
we’ll runblurb spliton each active branch,
removeMisc/NEWSfrom the repo entirely,
never runblurb splitever again,
and ride off into the sunset, confident that the world is now
a better place.The “next” directoryYou may have noticed thatblurb addadds news entries to
a directory callednext, andblurb releasecombines those
news entries into a single file named with the version.  Why
is that?First, it makes naming the next version a late-binding decision.
If we are currently working on 3.6.5rc1, but there’s a zero-day
exploit and we need to release an emergency 3.6.5 final, we don’t
have to fix up a bunch of metadata.Second, it means that if you cherry-pick a commit forward or
backwards, you automatically pick up the NEWS entry too.  You
don’t need to touch anything up–the system will already do
the right thing.  If NEWS entries were already written to the
final version directory, you’d have to move those around as
part of the cherry-picking process.Changelog1.1.0Support GitHub Issues in addition to b.p.o (bugs.python.org).
If “gh-issue” is in the metadata, then the filename will contain “gh-issue-<number>” instead of “bpo-“.1.0.7When word wrapping, don’t break on long words or hyphens.Use the-fflag when addingblurbfiles to agitcheckin.  This forces them to be added, even when the files
might normally be ignored based on a.gitignoredirective.Explicitly support the-helpcommand-line option.Fix Travis CI integration.Copyrightblurbis Copyright 2015-2018 by Larry Hastings.
Licensed to the PSF under a contributor agreement.